[TypeScript]union type, any, unknown (2)
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 연산자) 쓰려면 어떻게 할까요
var 어레이: number[] = [1,'2',3]
var 오브젝트: {data : number} = { data : '123' }
위 코드에 정의된 어레이와 오브젝트는 지금 타입 때문에 에러가 납니다.
var 어레이: (number | string)[] = [1,'2',3]
var 오브젝트: {data : (number | string) } = { data : '123' }
array와 object 자료에 number 또는 string이 들어올 수 있게 타입을 좀 고쳐치면 해결 됩니다
any type
any type은 아무 자료나 집어넣을 수 있는 타입입니다.
쉽게 비유하면 실드해제입니다.
let 이름: any = 'kim';
이름 = 123;
이름 = undefined;
이름 = [];
any 타입은 실드 해제 문법이기 때문에 갑자기 타입을 마구 바꿔도 에러가 나지 않습니다.
any 타입은 좋다고 막쓰면 안되는데 그럼 타입관련 버그가 생길 경우 왜 그런지 추적하기가 어려워 집니다
타입 실드를 안씌우면 타입스크립트를 쓸 이유가 없습니다.
그래서 비상시 쓰는 변수 타입체크 해제기능 이런 용도로 씁시다.
unknown type
요즘 타입스크립트는 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 타입을 써봅시다.
let 나이: string|number;
나이 + 1;
분명 자바스크립트에선 문자에도 +1 가능하고 숫자에도 +1 가능합니다.
근데 에러가 납니다
let 나이: unknown = 1;
나이 + 1;
분명히 나이라는 변수는 1인데 +1 안해줍니다. 둘다 같은 이유입니다
그래서 unknown 타입인 변수를 조작하려면
내가 조작할 변수의 타입이 무엇인지 확실하게 체크하는 narrowing 또는 assertion 스킬을 사용해야합니다.
그것이 타입스크립트의 근간이 되는 코딩방법이고
변수에 뭐가 들어있을지 애매한, 추측해야하는 상황이 나오는 시점에선 반드시 사용해야합니다.
(1) 다음 변수 4개에 타입을 지정해봅시다.
let user = 'kim';
let age = undefined;
let married = false;
let 철수 = [user, age, married];
허전하니까 변수 4개에 타입빨리 집어넣어봅시다.
(조건) age 변수엔 undefined 말고 숫자도 들어올 수 있습니다.
let user :string = 'kim';
let age :undefined | number = undefined;
let married :boolean = false;
let 철수 :(string|number|undefined|boolean)[]= [user, age, married];
(2) 학교라는 변수에 타입지정해보십시오.
let 학교 = {
score : [100, 97, 84],
teacher : 'Phil',
friend : 'John'
}
학교.score[4] = false;
학교.friend = ['Lee' , 학교.teacher]
let 학교 : {
score : (number|boolean)[],
teacher : string,
friend : string | string[]
}
= {
score : [100, 97, 84],
teacher : 'Phil',
friend : 'John'
}
학교.score[4] = false;
학교.friend = ['Lee', 학교.teacher]