Search
🌀

아이템 21. 타입 넓히기

명시적 타입 선언 없이 변수 할당 시 TS는 적절하게 타입 추론을 함
추론에는 한계가 있으므로 타입 추론을 제어하기 위한 방법 사용해야함

1. TS의 ‘넓히기' 타입 추론 과정

변수 초기화 시 타입 명시 X ⇒ TS가 타입 추론
interface Vector3 { x: number; y: number; z: number }; function getComponent(vector: Vector3, axis: 'x' | 'y' | 'z') { return vector[axis]; } let x = 'x'; // '타입 넓히기' 작동 => type: string let vec = { x: 10, y: 20, z: 30}; getComponent(vec, x); // error
TypeScript
복사
‘타입 넓히기’ 때 추론 가능한 타입은 여러가지 ⇒ TS는 명확성-유연성 사이에 균형 추구
const mixed = ['x', 1] // 하나의 값에 대해 여러가지 추론 가능한 타입이 존재 ['x', 1] ('x' | 1)[] [string, number] readonly [string, number] (string | number)[]; readonly (string | number)[] [any, any] any[]
TypeScript
복사

2. 정확한 ‘넓히기’ 추론을 위한 방법

1.
선언 시 const 사용
// (값의 경우) const 사용 => 재할당 가능성을 없애 충분히 좁은 타입으로 추론 const x = 'x' // type is "x" let vec = { x: 10, y: 20, z: 30 } getComponent(vec, x) // OK // (객체의 경우) const 사용 => 여전히 추론 가능한 타입이 여러 개 // TS는 객체 내 각 요소를 let으로 할당 된 것처럼 다룸 const v = { x: 1 } 타입 넓히기 작동 (x의 타입은 number) v.x = 3 // OK - 존재하는 프로퍼티에 다른 숫자 할당 v.x = '3' // error - 다른 타입 할당 불가 v.y = 4 // error - 다름 프로퍼티 추가 불가
TypeScript
복사
2.
명시적 타입 구문 제공
구체적으로 원하는 타입을 명시 ⇒ 타입 넓히기로 인한 혼선 없음
const v: { x: 1 | 3 | 5 } = { x: 1 } // Type is { x: 1 | 3 | 5; }
TypeScript
복사
3.
타입 체커에 추가 문맥 제공
아이템 26에서 다룸
4.
const 단언문 사용(as const)
as const 작성 시 TS는 최대한 좁은 타입으로 추론
// TS는 적절한 추론을 시행 const v1 = { x: 1, y: 2, } // Type is { x: number; y: number; } // as const 사용시 가장 좁은 타입으로 추론 const v2 = { x: 1 as const, y: 2, } // Type is { x: 1; y: number; } const v3 = { x: 1, y: 2, } as const // Type is { readonly x: 1; readonly y: 2; } // as const 사용시 배열을 튜플(+readonly)로 추론해서 사용 가능 const a1 = [1, 2, 3] // Type is number[] const a2 = [1, 2, 3] as const // Type is readonly [1, 2, 3]
TypeScript
복사