🤹🏻‍♀️ Javascript/🥎 Typescript

타입 추론, 타입 단언

ji-hyun 2022. 3. 6. 20:33

타입 추론

 

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/

 

TypeScript: 타입 추론과 타입 단언

TypeScript 를 도입하기가 망설여지는 이유 중 하나는 매번 일일이 변수를 선언할 때마다 타입을 선언해야하고 필요한 타입을 정의해야하는 비용에 대한 걱정일 것이다. 필요한 타입이 있을 때 타

hyunseob.github.io

 

 

 

'🤹🏻‍♀️ 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