TS)union type, any, unknown,Narrowing,Assertion

미누도 개발한다·2021년 10월 9일
0

타입스크립트

목록 보기
4/7

타입을 미리 정하기 애매할때 시리즈입니다.

전에 string | number 와 같은 타입을 union type 이라고 했습니다.
두 자료형을 모두 허용합니다.(union Type 자체가 type 입니다. 두 자료형을 합친 개념이라고 쉽게 생각하면 쉽습니다.)

  • union Type
let person: number|string = 20;
let person: number|string = '홍길동';

// object 예시
let obj: {a:string|number } = {a:'홍길동'}
let obj: {a:string|number } = {a:20}

// array 예시
let arr:(number|string)[] = [1,'2',3]
  • any

    모든 자료형을 허용 해줍니다.
    중요한 포인트는 , 컴파일러의 체크를 피해간다는 점입니다.
    즉, 변수의 타입쉴드를 없앤다고 보면 됩니다. any를 쓰는순간 그냥 js가 되어버립니다.
    어쩔수 없을때 사용합니다. any를 쓰면 타입스크립트를 쓰는 의미가 없으니까요!

  • unknown
    any랑 유사할수는 있지만 조금 더 안전합니다. 타입 쉴드가 동작하기 때문입니다.
let foo:unknown;
foo = 123; //가능
foo ='string' //가능

let foo2:string ;
foo2 = foo; // 불가능 string 자료형에 unknown자료형을 넣을수 없쥬

any를 사용하게되면 타입쉴드가 동작하지않습니다.

let foo:any;
foo = 123;
foo ='string'

let foo2:string;
foo2 = foo

any는 모든자료형이 가능하니까 대입이 되나보다~ 가 아니라 그냥 타입쉴드가 동작하지 않는구나 라고 생각하시면 됩니다!


타입스크립트는, 변수끼리 연산시, 엄격한 타입체크를 합니다.
예를들어, 자바스크립트 에서는, 1+'1' 과 , 1+1 모두 가능합니다.
그렇다면 아래 코드를 볼까요?

let age: string|number;
age+2 // 에러 

그 이유는 , unionType은 string,number 둘중에 하나가 아닌, 그 자체가 자료형이기 때문입니다.
따라서 위 연산이 가능하려면 number인지 string 인지 타입을 명시적으로 지정해 주어야합니다.
이를 Narrowing, Assertion 을 통해 해결합니다.
애매~한 변수 타입을 한가지로 좁혀주는거죠!

Narrowing을 하기전 사전지식으로 함수는 어떻게 타입지정을 하는지 알아보겠습니다.


function foo(x:number):number{
  return x*10
}

const foo = (x:number):number => {
  return x*10
}
// 매개변수의 type, 함수 중괄호 전에 return type을 지정합니다. 

매개변수가 들어올수도 있고, 안들어 올수도 있는경우는 ? 를 사용합니다.

const func = (x?:number):void => {
	console.log(x)
}

포인트! 옵셔널은 type | undefined와 같습니다.

즉, 위 의 옵셔널 코드는, 아래의 union type으로 번역됩니다.

const func = (x: number|undefined):void => {
	console.log(x)
}
func(5)

Q. 아래의 코드는 왜 안될까요?

const func = (x?:number):number => {
	return x*20
}
func(5)

맞습니다. x는 union type 이기 때문입니다.


간단히 함수까지 알아보았네요. 이제 Narowwing과 Assertion 을 해보겠습니다.

Narrowing

 function func(x :number|string){
   if(typeof x == 'number'){
     return x+1
   }else{
     return x+'1'    
   }
 }

function func(x :number|string){
  let arr:number[]  = [];
  if(typeof x =='number'){
    arr[0] = x;
  }else {

  }
}

위의 예시처럼, x의 타입을 하나로 확실하게 정해줘야 에러가 뜨지않습니다.

현재 변수의 타입을 특정지을 수 있으면 모두 인정됩니다.
Narrowing을 판정해주는 대표적인 문법은 아래와 같습니다.

  • typeof 변수
  • 속성명 in object
  • 인스턴스 instanceof 부모

Assertion

타입을 덮어씌우는것을 의미합니다.

function func(x :number|string){
  let arr:number[]  = [];
  
  arr[0] = x as number; // if문을 안썼는데, 타입이 확정됩니다.

}

Assertion의 용도는 아래와 같습니다.

1.Narrowing 할 때
따라서 아래와 같이 사용하면 안됩니다.

let num:number = 5;
num as string; //에러 마우스를 올리면 자세한 로그를 확인할수있음

as 는 unionType과 같이 아직 확정되지않은 타입을 확정지을때 사용하는것 입니다.


2.무슨 타입인지 확실할 때

function func(x :number|string){
  let arr:number[]  = [];
  
  arr[0] = x as number; 

}
func('string')

위 코드는 , 에러가 나야하지만 as로 number타입으로 덮어씌우기때문에,
에러캐치를 하지못합니다.

따라서 디버깅할때만 주로 사용하게 됩니다.


다음정리한 내용들은 다음 포스팅에서!
profile
빨리 가는 유일한 방법은 제대로 가는 것이다

0개의 댓글

Powered by GraphCDN, the GraphQL CDN