참고자료: 타입스크립트는 왜 그럴까?
인프콘 신청했지만 탈락으로 인해.. 온라인으로 공유된 세션을 정리해보려고 한다.
타입스크립트는 집합으로 모든걸 이해할 수 있다.
let a: number = 10; // number 타입
let b: 10 = 10; // number 리터럴 타입
슈퍼 타입과 서브타입으로 둘의 관계를 나타낼 수 있고, 타입스크립트의 전체적인 계층은 다음과 같다.
상위로 갈수록 슈퍼타입으로 되어 있고 그중 Any, Unknown, Never를 중심으로 설명한다.
타입 호환성은 타입간의 관계를 기준으로 판단되는데 슈퍼 타입에서 서브타입으로 호환되는 것을 다운 캐스팅, 그 반대를 업 캐스팅이라고 하는데, 타입스크립트에서는 업 캐스팅만 허용이 된다.
아까의 예시에서
let a: number = 10; // number 타입
let b: 10 = 10; // number 리터럴 타입
a = b; // 가능
b = a; // 에러
b = a 는 다운 캐스팅에 해당되므로 타입스크립트에서는 에러를 내게 된다.
타입스크립트에서는 가장 상위에 있는 타입(Unknown), 가장 하위에 있는 타입(Never), 계층 밖에 존재하는 타입(Any) 3가지 특수한 타입이 존재한다.
Unknown 타입은 슈퍼 타입이므로 업 캐스팅이 가능하므로 모든 타입의 값이 들어올 수 있다.
let a: unknown = 10; // 슷지
let b: unknown = "2"; // 문자열
let c: unknown = true; // boolean
let d: unknown = null; // null
let e: unknown = undefined; // undefined
let f: unknown = []; // 빈 배열
let g: unknown = {}; // 빈 객체
let H: unknown = () => {}; // 함수
Unknown타입은 가장 상위에 존재하므로 어떤 타입이 들어오더라도 업캐스팅에 해당되어 오류가 없다.
그렇기에 반대로 Unknown 타입은 어디에도 타입 지정을 할 수 없다.
이러한 타입은 어디에 사용할 수 있을까?
function someUtil(value: unknown) {
if (typeof value === 'number') {
//...
} else if (typeof value === 'string') {
}
}
어떠한 함수에 들어오는 값이 무엇인지 모르고 그 함수안에서 타입에 따라 분리가 필요할 때 유용하기 사용할 수 있다.
never 타입은 가장 하위에 있는 타입으로 모든 타입에 대입할 수 있다.
그렇기에 반대로 never에 타입을 지정하면 다운 캐스팅에 해당되므로 어떠한 타입도 들어올 수 없다.
이러한 타입은 어디에 사용할 수 있을까?
function doNotExecute(error: never) {
throw new Error();
}
type Color = "Green" | "Blue" | "Red";
function getColorName(color: Color) {
switch(color) {
case "Green":
break;
case "Blue":
break;
default:
// 도달 하면 안되는 곳
return doNotExecute(color);
break;
}
}
"Green" 과 "Blue" 그리고 "Red" 3가지만 확인하는 swtich문의 완전성을 보장할 수 있다.
switch문에 현재 "Red"를 통과 못하니 아래 함수가 실행되어 에러를 내뱉는다.
any는 어디에도 넣을수 있고 어떠한 타입을 받을 수 있다.
예외적으로 never타입에는 대입이 안된다. 그 이유는 never는 어떠한 타입도 받지 않기에 any또한 받지 않는 것이다.
// 1. type A = never & string; // 2. type B = never | string; // 3. type C = unknown & string; // 4. type D = unknown | string;
- never는 하위의 타입이고 String 타입과의 교잡합은 당연히 never 타입이다.
- 반대로 never와 String 타입과의 합집합은 String타입이 더 상위의 집합이므로 String 타입이다.
- unknown은 상위의 타입이고 string 타입은 unknown 보다 하위의 타입이므로 교집합은 String타입이다.
- 마지막으로 unkown 과 string타입의 합집합은 더 큰 집합인 unkonwn타입이다.
let person: Person = {
name: "홍길동"
}
let student: Student = {
name: "홍길동"
school: "00고등학고"
}
student = person; // 다운 캐스팅 (x)
person = student; // 업 캐스팅 (o)
객체 타입에도 당연하게 타입이 더 좁은 student에 person 타입을 대입하는 다운 캐스팅은 에러를 내뱉는다.