TypeScript

[TS]타입을 미리 정하기 애매할 때(union type, any, unknown)

MoZZANG 2022. 10. 21. 13:51

변수에 들어올게 string일지 number일지 아직 애매하다면

방법이 몇가지 있습니다. 

 

 

가장 좋은 Union type 사용

 

"이 변수엔 string 또는 number가 들어올 수 있습니다~" 라고 타입정의를 하고싶으면 | 연산자를 씁시다.

OR 연산자 같은 느낌인데 이런 타입을 전문용어로 Union type 이라고 부릅니다. 

 

 

let 이름: string | number = 'kim';
let 나이: (string | number) = 100;

 

심심하면 괄호쳐도 됩니다.

이러면 name, age 변수엔 string 또는 number만 들어올 수 있습니다. 

그리고 할당하는 순간 타입은 string 또는 number 중 하나로 변합니다.

 

 

 

 

그럼 array, object 자료 만들 때 union type (OR 연산자) 쓰려면 어떻게 할까요

 

let 어레이: number[] = [1,'2',3] //[x]
let 오브젝트: {data : number} = { data : '123' } //[x]

 

 

위 코드에 정의된 어레이와 오브젝트는 지금 타입 때문에 에러가 납니다.

array와 object 자료에 number 또는 string이 들어올 수 있게 타입을 좀 고쳐보면

 

let 어레이: (number | string)[] = [1,'2',3]
let 오브젝트: {data : (number | string) } = { data : '123' }

 

특징은 변수에 정의된 Union 타입은 할당과 동시에 OR 역할이 사라집니다.

array, object에 정의된 Union 타입은 OR 연산자가 유지됩니다. 

 

 

 

 

 

 

아니면 any 타입이라는 것도 있습니다

 

아무 자료나 집어넣을 수 있는 타입입니다.

쉽게 비유하면 실드해제입니다.

 

let 이름: any = 'kim';
이름 = 123;
이름 = undefined;
이름 = [];

 

any 타입은 실드 해제 문법이기 때문에 갑자기 타입을 마구 바꿔도 에러가 나지 않습니다.

any 타입은 좋다고 막쓰면 안되는데

그럼 타입관련 버그가 생길 경우 왜 그런지 추적하기가 어려우니까요. 

타입 실드를 안씌우면 타입스크립트를 쓸 이유가 없습니다. 

그래서 비상시 쓰는 변수 타입체크 해제기능 이런 용도로 씁시다.

 

 

 

 

 

 

 

any 보다는 unknown 타입이 나은듯 

 

요즘 타입스크립트는 unknown 타입을 사용합니다.

any와 똑같이 모든 타입을 집어넣을 수 있습니다. 

 

let 이름: unknown = 'kim';
이름 = 123;
이름 = undefined;
이름 = [];

 

이래도 에러가 나지 않습니다.

아직 어떤 타입이 들어올지 모를 경우, 다양한 타입을 집어넣어야할 경우 이걸 사용해보시길 바랍니다. 

중요한 특징은

1. unknown 타입엔 모든 자료 다 집어넣을 수 있음

2. 자료집어넣어도 타입은 그대로 unknown입니다. 

 

 

 

let 이름: unknown;

let 변수1: string = 이름;
let 변수2: boolean = 이름;
let 변수3: number = 이름;

당연히 unknown 타입을 다른 곳에 집어넣으려고 하면

그쪽 실드가 발동해서 에러가 납니다. 

(any는 안그럼)

 

 

 

let 이름: unknown;
이름[0];
이름 - 1;
이름.data;

 

이래도 에러가 납니다.

(any는 안그럼)

 

 

왜냐면 타입스크립트는 정확하고 확실한걸 좋아합니다.

확실하지않은 타입에 뺄셈해주고 그런거 싫어합니다. 

숫자가 아닌걸 뺄셈할 수는 없으니까요. 

타입스크립트에선 뺄셈은 number 류의 타입만 할 수 있고 

.name 이런건 object 류의 타입만 할 수 있다라고 미리 정의되어있습니다. 

 

 

그래서 결론은 아직 뭘 집어넣을지 모르겠는데 약간의 안정성을 도모하고 싶으면 unknown 타입을 써봅시다. 

근데 실은 코드짜다가 any, unknown 부여할 경우는 별로 없습니다. 

 

 

 

 

Q1. 이 코드는 왜 에러가 나는 것이죠?

let 나이: string|number;
나이 + 1;

분명 자바스크립트에선 문자에도 +1 가능하고 숫자에도 +1 가능합니다.

근데 저건 에러가 납니다.

 

 

Q2. 이 코드도 왜 에러가 나는 것이죠?

let 나이: unknown = 1;
나이 + 1;

분명히 나이라는 변수는 1인데 +1 안해줍니다.

 

 

이유는

타입스크립트는 언제나 확실한걸 좋아한다고 했습니다.

지금 변경하려는 변수의 타입이 확실해야 연산을 수행해줍니다. 

그래서 -1은 확실하게 왼쪽에 있는게 number 타입일 때만 가능합니다.

unknown은 number타입이 아닙니다.

string|number 이것도 number 타입이 아닙니다. (union type은 새로운 타입을 하나 만든 겁니다)

+1도 마찬가지입니다. 

 

 

그래서 unknown 타입인 변수를 조작하려면

내가 조작할 변수의 타입이 무엇인지 확실하게 체크하는 narrowing 또는 assertion 스킬을 사용해야합니다. 

그것이 타입스크립트의 근간이 되는 코딩방법이고

변수에 뭐가 들어있을지 애매한, 추측해야하는 상황이 나오는 시점에선 반드시 사용해야합니다.

 

 

 

 

<출처 : 코딩애플 - 빠르게 마스터하는 타입스크립트>