as const는 Typescript3.4버전에서 추가된 const assertion기능을 활용하기 위한 기능이다.
const assertion은 '상수라는 주장'인데 '원래 상수가 아닌것을 상수인것으로 선언해주는 기능'이라고 생각할 수 있다
그럼 왜 상수가 아닌것을 상수로 만들어줘야 할까?
let은 string이라는 타입을 추론하지만, const는 할당된 그 값 자체를 Type으로 받아오는 차이를 확인할 수 있다
참고로 할당된 값 자체를 Type으로 추론하는 것을 Literal Type으로 부른다. 특정 문자열을 Type으로 취급한다면 String Literal type이다.
그럼 let 상수에 as const
타입을 추가해서 const assertion을 사용하면 어떻게 될까?
as const
를 해주었기 때문에 String Literal Type이 적용되어 최초 선언한 'hello'값 외의 값을 할당할 수 없는걸 확인할 수 있다.
Object의 Value는 상수가 아니다. Object의 Key가 존재한다고 정의할 수는 있지만, 특정 Key에 특정 Value가 와야한다는건 구체적으로 지정할 수가 없다. Object가 본질적으로 구조적인 데이터 형태로써 가변적인 데이터값을 저장하기 위해 탄생했기 때문이다.
가변적인 Object를 enum스럽게 활용하고 싶을때 'as const'를 사용할 수 있다
const ODirection = {
Up: 0,
Down: 1,
Left: 2,
Right: 'hi',
}
type Key = keyof typeof ODirection;
type Value = (typeof ODirection)[Key];
Key
은 ODirection 객체의 key타입들을 정확히 추론하고 있으나,
Value
는 'string | number'정도의 타입만 추론하고 있다. 이런 경우 조금 더 확정적 추론을 위해 'as const'를 사용하면 되는데,
const ODirection = {
Up: 0,
Down: 1,
Left: 2,
Right: 'hi',
} as const // <-- 추가
type Key = keyof typeof ODirection;
type Value = (typeof ODirection)[Key];
Value
에 대한 타입을 더 명확하게 추론할 수 있게된다.
위에서 따로 언급하지는 않았지만 'as const'를 사용하면서 'const enum'의 단점을 보안하고, 추천하고 있는게 현 주소이다.
Value만 받아와서 Literal Type으로 지정하고 싶다면 'as const'문법으로도 충분하다.