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개의 댓글