효율적으로 상수 관리하기
타입스크립트에서는 포괄적인 타입(string, number, ...) 외에도 정확한 값을 타입으로 설정하는 것이 가능하다.
let title: 'typescript';
title = 'javascript'; // Type 'javascript' is not assignable to type 'typescript'
타입스크립트에서는 컴파일러가 자동으로 타입을 추론하는 기능을 제공한다. let은 변수의 값을 언제든 바꿀 수 있기 때문에 더 포괄적인 타입으로 값을 추론하고, const의 경우는 변경이 불가능하기 때문에 리터럴 타입으로도 추론된다.
let title = 'typescript'; // let title: string
const content = 'typescript; // const content: 'typescript'
타입 단언(Type Assertion)을 활용한 상수 관리
let 변수의 경우에도 const처럼 리터럴 타입으로 추론해줄 수 있는데, 그 때 사용하는 것이 as const이다.
let title = 'typescript' as const; // let title: 'typescript'
타입 단언을 활용해서 상수를 관리하는 방법에 대해 알아보자.
const Colors = {
red: '#FF0000',
blue: '#0000FF',
green: '#008000'
}
Colors 변수 내부에 추론된 값을 보면 각 속성이 원시 타입으로 추론된다. 이는 const로 객체를 선언했지만, 객체 내부의 값들은 언제든지 바꿀 수 있기 때문이다.
이 때 타입 단언을 통해 Colors 내부값의 타입을 리터럴 타입으로 변경할 수 있고, 편리하게 상수를 관리할 수 있다.
const Colors = {
red: '#FF0000',
blue: '#0000FF',
green: '#008000'
} as const
enum을 통한 상수 관리
export enum Colors {
red="#FF0000",
blue="#0000FF",
green="#008000",
}
타입스크립트에서는 enum이라는 객체를 통해 상수를 쉽게 관리할 수 있다.
enum은 타입스크립트에서 제공하는 문법을 아래와 같은 특징을 가진다.
- enum은 js 객체이나, 내부 속성을 임의로 변경 불가
- enum의 내부 key는 반드시 리터럴 타입(string or number)으로만 사용 가능
- enum의 속성값도 리터럴 타입(string or number)만 사용 가능
enum vs as const
그렇다면 상수 관리에 enum, as const 중에 어떤 것을 쓰는 것이 더 좋을까?
enum과 as const는 탄생한 목적 자체가 다르다. enum은 서로 연관된 상수들을 하나의 네임스페이스로 묶어 추상화하기 위해 도입된 것이다. 이를 통해 코드만 보더라도 의도를 명확히 알 수 있어 가독성을 높일 수 있다.
반면 as const는 타입 단언의 한 종류로써 리터럴 타입의 추론 범위를 줄이고 값의 재할당을 막기 위한 목적으로 만들어졌다.
Object(or Array) 리터럴의 as const
let title = 'typescript' as const
as const를 위와 같이 쓸 수도 있지만 그럴 바에는 아예 const로 선언하는 게 좋을 것이다.
그렇지만 원시타입이 아닌 Object나 Array 타입이라면 얘기가 달라진다. 이 둘은 참조 타입이기 때문에 const로 선언해도 내부 프로퍼티의 추론 범위가 한정되지도 않고, 값을 변경할 수도 있다.
const language = {
korean: "ko", // "ko"로 추론, readonly 프로퍼티로 변경
english: "en", // "en"로 추론, readonly 프로퍼티로 변경
} as const;
// Error: Cannot assign to 'korean' because it is a read-only property
language.korean = "kkk";
// Error: Cannot assign to 'english' because it is a read-only property.
language.english = "eee";
이럴 때 as const를 사용하면 객체의 모든 프로퍼티들이 readonly로 변경되고, 각 프로퍼티의 타입이 할당된 리터럴 값으로 추론된다.
중첩 객체(배열)의 프로퍼티들도 as const를 사용하면 readonly로 변경되고 리터럴 값으로 추론된다.
const obj = {
a: 10,
b: [20, 30],
c: {
d: {
e: {
greeting: "Hello",
},
},
},
} as const;
이렇듯 as const를 사용하면 원시 타입이든 참조 타입이든 값의 재할당을 막기 때문에 의도치않은 변경으로 인한 오류를 없앨 수 있다. 또한, 리터럴 타입의 추론 범위가 리터럴 값 자체로 한정되면서 좀 더 안전하게 코드를 작성할 수 있다.
References
https://blog.toycrane.xyz/typescript에서-효과적으로-상수-관리하기-e926db079f9
https://velog.io/@logqwerty/Enum-vs-as-const
'TIL' 카테고리의 다른 글
[TIL] 23.03.15 TS 핸드북 - Typeof Type Operator (0) | 2023.03.16 |
---|---|
[TIL] 23.03.08 TS 핸드북 - More on Functions (0) | 2023.03.09 |
불필요한 node_modules 한번에 삭제하기 (0) | 2023.01.31 |
[TIL] 23.01.26 패키지 잠금 파일(package-lock.json, yarn.lock) (0) | 2023.01.27 |
[TIL] 23.01.17 프리온보딩 챌린지 3회차 (0) | 2023.01.18 |