타입스크립트에서 변수를 const로 선언할 때와 let으로 선언할 때 타입 추론이 다르게 일어난다.
let a = 'hi'; // let a: string
const b = 'hi'; // const b: "hi"
타입스크립트는 string literal type을 지원하여 특정 문자열 자체를 타입으로 다룰 수 있다. const로 선언한 변수는 위와 같이 string이라는 넓은 범위의 타입 대신 구체적으로 딱 하나의 문자열인 'hi'를 가리키게 된다.
이는 다른 number 타입에서도 마찬가지이다.
let a = 1; // let a: number
const b = 1; // const b: 1
그런데 배열이나 객체의 경우에는 const로 선언하여도 문자열이나 숫자일 때처럼 구체적으로 범위를 좁히지 않는다.
const a = [1, 'hi']; // const a: (string | number)[]
const b = {
num: 1,
str: 'hi'
};
// const b: {
// num: number;
// str: string;
// }
TypeScript 3.4 버전부터 도입된 const assertion을 활용하여 이런 경우에도 타입 추론의 범위를 좁힐 수 있게 되었다.
const a = [1, 'hi'] as const; // const a: readonly [1, "hi"]
// const a = <const>[1, 'hi'];와 동일
const b = {
num: 1,
str: 'hi'
} as const;
// const b: {
// readonly num: 1;
// readonly str: "hi";
// }
변수 선언문 뒤에 as const를 추가하거나 리터럴 앞에 <const>를 붙이면 const assertion이 적용된다. (단, <const>는 tsx 파일에서 사용할 수 없으며, ts파일이라도 typescript eslint를 사용하고 있다면 @typescript-eslint/consistent-type-assertions 규칙에 의해 as const로 변경하라는 경고가 발생할 것이다.)
let으로 선언한 변수도 뒤에 as const를 붙여서 동일하게 const assertion을 적용할 수 있다.
let a = 'hi' as const; // let a: "hi"
let b = 1 as const; // let b: 1
const assertion은 문자열이나 숫자, 배열이나 객체 리터럴 외에도 enum members, boolean에도 적용할 수 있다. 그러나 아래와 같이 삼항 연산자를 사용한 경우에는 const assertion을 적용할 수 없다.
let boolean = true;
let a = (boolean ? 'yes' : 'no') as const
// 'const' 어설션은 열거형 멤버나 문자열, 숫자, 부울, 배열 또는 개체 리터럴에 대한 참조에만 적용할 수 있습니다.ts(1355)
이러한 경우에는 삼항 연산자의 두 선택문 모두에 as const를 사용하여 타입을 좁힐 수 있다.
let boolean = true;
let a = boolean ? 'yes' as const : 'no' as const; // let a: "yes" | "no"
참고자료
https://medium.com/@seungha_kim_IT/typescript-3-4-const-assertion-b50a749dd53b
https://mainawycliffe.dev/blog/const-assertion-in-typescript/
'IT > TypeScript' 카테고리의 다른 글
[TS] Node.js 환경에서 TypeScript 사용하기 (0) | 2022.11.23 |
---|---|
[TS] CRA에서 tsconfig paths로 절대경로 설정하기 (react-app-alias) (0) | 2022.07.20 |
[TS] TypeScript가 SVG 파일을 import하지 못하여 에러가 발생할 때 (0) | 2022.06.30 |
[TS/Webpack/Jest] tsconfig paths를 사용할 때 Webpack, Jest 설정하기 (0) | 2022.06.27 |