타입 추론
let bool = true;
const arr = [1, 2, 3];
const tuple = [true, 1]; //
bool = 1; // Error!
3번째는 배열의 요소가 각각 boolean과 number이기에 최종적으로 추론되는 타입은 boolean과 number의 유니온 타입의 배열, 코드로 나타내면 (boolean | number)[] 이다.
여기에서 배열에서 사용된 요소들의 타입을 각각 추론하여 유니온 타입으로 만들어 내는 방식을 TypeScirpt 에서는 Best common type이라고 부른다.
Best common type
Best common type 은 말 그대로 가장 일반적인 타입이다. 여러가지 자료형이 배열 내부에서 사용되고 있을 때, 그 여러가지 자료형을 포괄할 수 있는 가장 일반적인 자료형을 추론하는 것이다. 그 결과로 위의 예제에서는 true와 1을 포괄할 수 있는 자료형인, (boolean | number) 가 추론된 것이다.
Best common type 은 대부분의 경우에 유니온 타입으로 추론되지만 예외적인 케이스도 몇 가지 있다. 여기서는 생략.
타입 단언
TypeScript 의 타입 추론 기능은 매우 강력하지만 어쩔 수 없는 한계가 존재한다. 타입 단언은 TypeScript 컴파일러가 타입을 실제 런타임에 존재할 변수의 타입과 다르게 추론하거나 너무 보수적으로 추론하는 경우에 프로그래머가 수동으로 컴파일러한테 특정 변수에 대해 타입 힌트를 주는 것이다.
class Character {
hp: number;
runAway() {
/* ... */
}
isWizard() {
/* ... */
}
isWarrior() {
/* ... */
}
}
class Wizard extends Character {
fireBall() {
/* ... */
}
}
class Warrior extends Character {
attack() {
/* ... */
}
}
function battle(character: Character) {
if (character.isWizard()) {
character.fireBall(); // Property 'fireBall' does not exist on type 'Character'.
} else if (character.isWarrior()) {
character.attack(); // Property 'attack' does not exist on type 'Character'.
} else {
character.runAway();
}
}
이 코드는 컴파일 에러를 낸다. Character 클래스에는 fireBall, attack 메소드가 선언조차 되어있지 않기 때문이다. 하지만 프로그래머 입장에서 바라보면 isWizard라는 메소드를 통해 확실히 그 캐릭터가 Wizard 인스턴스라는 걸 보장할 수 있다면, if 블록 안에서는 당연히 fireBall이라는 메소드를 사용할 수 있어야 한다.
이 때, 타입 단언으로 적절한 타입을 다시 선언해줄 수 있다.
function battle(character: Character) {
if (character.isWizard()) {
(character as Wizard).fireBall(); // Pass
} else if (character.isWarrior()) {
(character as Warrior).attack(); // Pass
} else {
character.runAway();
}
}
해당 변수가 실제로 Wizard 인스턴스가 아니더라도 as 키워드를 통해서 타입 단언을 해줄 수 있기 때문에, 타입 단언은 주의해서 사용해야 한다. 실제로도 as any 라는 치트키로 대부분의 컴파일 에러를 해결할 수 있다. 하지만 이런 키워드가 코드 베이스에 득시글 거릴 수록 TypeScript 를 사용해서 얻는 장점이 점차 사라져가기 때문에, 기왕 TypeScript 를 사용하기로 마음 먹었다면 as와 any는 가능한 적게 사용하는 것이 좋다. 물론, 아예 사용하지 않기는 어렵다.
https://hyunseob.github.io/2017/12/12/typescript-type-inteference-and-type-assertion/
'🤹🏻♀️ Javascript > 🥎 Typescript' 카테고리의 다른 글
[TS] 조건부 타입 (0) | 2022.05.07 |
---|---|
[TS] 제네릭 (0) | 2022.05.07 |
타입스크립트 에러 (0) | 2022.02.25 |
체크박스 typescript (useState Type) (0) | 2022.02.25 |
material ui - Pagination (0) | 2022.02.25 |