본문으로 건너뛰기

아이템26

타입 추론에 문맥이 어떻게 사용되는지 고려하기

  • 타입스크립트는 추론시 단순한 값만 고려하지 않고 존재하는 곳의 문맥까지 고려한다.
// string 추론
let nameLet = "kim";
type Name = typeof nameLet;

// const 추론
const nameConst = "kim";
type NameC = typeof nameConst;

튜플 사용시의 문제점

  • 문자열 리터럴 타입과 마찬가지로 튜플 타입에서도 문제가 발생한다.
declare function panTo(where: [number, number]): void;

const tuple = [1, 2];

// (4) Error: 'number[]' 형식의 인수는 '[number, number]' 형식의 매개 변수에 할당될 수 없습니다.
panTo(tuple);
  • 위 코드는 [number,number]가 아닌 number[]로 추론되어 문제가 발생한다.
  • 이를 해결하기 위해 as const를 사용하면 내부까지 상수임을 타입스크립트에게 알려준다.
function panTo(where: [number, number]): void;

const tuple = [1, 2, 3] as const;

// 'readonly [1, 2, 3]' 형식의 인수는 'readonly [number, number]' 형식의 매개 변수에 할당될 수 없습니다.
panTo(tuple);
  • 다만 이런 방법은 너무 과하게 정확해 panTo타입의 시그니처를 where 내용이 불변임을 보장하지 못한다. 이를 해결하기위해 readonly를 붙여서 문제를 해결해야한다.
 function panTo(readonly : where :[number, number]): void;

객체 사용시 주의점

  • 객체의 경우에도 튜플처럼 주솟값을 갖는 참조에 대한 변경 불가능이라는 의미를 갖기 때문에 내부의 property는 일반적으로 let으로 선언한 변수처럼 타입 부여((6))합니다.
const champion = {
name: "Aatrox",
speed: 345,
};
/**
* (6)
* {
* name: string;
* speed: number;
* }
*/

const champion = {
name: "Aatrox" as const,
speed: 345,
};
/**
* {
* name: "Aatrox";
* speed: number;
* }
*/

const champion = {
name: "Aatrox",
speed: 345,
} as const;
/**
* {
* readonly name: "Aatrox";
* readonly speed: 345;
* }
*/

콜백을 상수로 뽑아내면 문장이 소실되고 오류가 발생한다.

  • 이를 해결하기 위해 const 사용시에는 매개변수에 타입을 줘야한다.

Item 26 결론

  • 별도의 변수로 뽑아서 사용한다면 타입 선언을 추가하는 방법 고려하기
  • 정말 상수라면 타입 단언(as const)을 사용하고, 타입 단언에서 문제가 있다면 사용한 곳에서 발생하는 것을 인지하기