아이템 21. 타입 넓히기 #
" 아이템 7에서 설명한 것처럼 런타임에 모든 변수는 유일한 값을 가집니다. “
런타임(=자바스크립트) 시에는 모든 변수가 값을 가진다.
그러나 타입스크립트가 작성된 코드를 체크하는 정적 분석 시점에는, 변수는 ‘가능한 값들의 집합’인 타입을 가진다.
넓히기 (widening) #
상수를 사용해서 변수를 초기화할 때, 타입을 명시하지 않으면 타입 체커는 타입을 추론/결정해야 한다.
= ‘가능한 값들의 집합’(타입)을 추론해야 한다.
타입스크립트에서는 이 과정을 ‘넓히기(widening)’ 라고 부른다.
‘넓히기’가 진행될 때, 가능한 값의 범위를 최대한 좁히되 오류(잘못된 추론)는 발생하면 안된다.
= ‘명확성’과 ‘유연성’ 사이에 균형을 유지하려고 한다.
let x = 'x';
위 코드에서 x
는 string
으로 추론된다.
(let
이기 때문에) x
에는 이후에
'asdsadas'
라는 값이 들어갈 수도,'dysdfds'
라는 값이 들어갈 수도 있다.
따라서, 타입스크립트는 ‘가능한 값의 범위(타입)‘을 string 으로 추론했다.
넓히기 제어 : const
#
위의 예시를 아래와 같이 수정해보자.
const x = 'x';
x
는 "x"
타입으로 추론된다.
(const
이기 때문에) x
에는 이후 값이 변경되지 않는다.
따라서, 타입스크립트는 가능한 값의 범위를 최대한 구체적으로(좁게) 추론할 수 있다.
” x는 재할당될 수 없으므로 타입스크립트는 의심의 여지 없이 더 좁은 타입(“x”)로 추론할 수 있다. “
그러나 const 가 만능은 아니다. (with 객체, 배열) #
객체, 배열인 경우에는 여전히 문제가 남아있다.
요소들을 어떤 타입으로 추론해야할 지 알 수 없기 때문이다.
객체의 경우 타입스크립트의 넓히기 알고리즘은 각 요소를 let
으로 할당된 것처럼 다룬다.
= 추상적인 타입으로 추론해야 한다.
= 구체적인 타입(좁은 타입)으로 추론할 수 없다.
타입 추론의 강도를 제어하는 방법 1 : 명시적 타입 구문 #
명시적으로 타입을 작성해준다.
const x: 1|3|5 = 1;
타입 추론의 강도를 제어하는 방법 2 : 추가적인 문맥 제공 #
함수의 매개변수로 값을 전달하거나하는 등의 문맥을 의미한다.
타입 추론의 강도를 제어하는 방법 3 : const 단언문 #
변수 선언 시에 사용하는
let
,const
와 혼동해서는 안된다.
값 뒤에 타입 단언(as const
)을 사용하면 타입스크립트는 ‘최대한 좁은 타입’으로 추론한다.
const v1 = {
x: 1,
y: 2,
}; // 타입 : { x: number; y: number; }
const v1 = {
x: 1 as const,
y: 2,
}; // 타입 : { x: 1; y: number; }
const v1 = {
x: 1,
y: 2,
} as const; // 타입 : { readonly x: 1; readonly y: 2; }
const a1 = [1, 2, 3]; // 타입 : number[]
const a2 = [1, 2, 3] as const; // 타입 : readonly [1, 2, 3]
* 넓히기로 인해 오류가 발생한다고 생각되면, 타입 추론의 강도를 제어하는 방법(명시적 타입 구문, 추가적인 문맥 제공, const 단언문)을 고려할 수 있다.
요약 & 정리 #
- ‘넓히기’ 개념을 이해하자.
- 동작(or 추론)에 영향을 주는
const
, 타입 구문, 문맥,as const
를 이해하자.