TypeScript: Handbook - Enums- 23년 8월 13일 기준
타입스크립트의 Enum을 매우 신중하게 사용해야 하고, 가급적 지양해야 한다는 것을 배웠지만, 자세한 내막을 알기 위해
타입스크립트 공식 문서의 Enums 레퍼런스를 살펴보았습니다.
공식문서는 확실히 다른 TS 개발자들의 블로그글들처럼 Enum을 비판하는 것이 아니라, 담담한 어조로 Enum의 특징과 사실들만을 나열하고 있습니다. 대충 읽다보면 대수롭지 않게 넘길 수도 있지만, 곰곰이 생각해보면 부작용이 만만치 않게 느껴지기 때문에, 경각심을 가지고 읽는 것이 좋겠습니다.
빨리 보는 나만의 결론:
enum보다는 object as const 를 사용하자.
타입스크립트는 Numeric enums와 String-based enums를 지원한다.
Numeric enum: auto-incrementing
string enum: serializable (디버깅할 때 읽기 편하다)
둘을 다 섞을 수도 있는데 권장하지 않는다. (heterogeneous)
만약,
위와 같다면 constant 라고 유추된다.
나머지는 모두 computed이다.
위에서 말한 constant enum members 중에서 특별한 부분집합이 있는데 바로 literal enum members 이다.
Literal enum member의 정의:
이 경우, enum members 자체도 타입으로 취급된다!
그리고 Enum type은 enum members의 Union이 된다.
Enum은 실제 JS 오브젝트로 만들어진다.
일반적인 타입과 달리 Enum은 실제 오브젝트이기 때문에 keyof 보다는 keyof typeof 을 사용해야 한다.
const a = Enum.A;
"A" === Enum[a];
이걸 허용한다. 즉, Enum member의 string 이름을 가져올 수 있다.
enum 앞에 const를 붙이면, 컴파일 타임에만 존재하는 enum이 된다!
매우 유용한 게 아닌가 했으나, 긴 설명을 보니 무언가 문제가 많은 듯 하다. 밑에서 언급하는 Objects as const 와의 차이점이 궁금하다.
생략
모던 타입스크립트에서는 만약 오브젝트에 as const 를 붙이는 것만으로 충분하다면 'you may not need an enum', 즉 enum이 필요하지 않을 수도 있다!
대부분의 경우에 많은 자료들, 그리고 타입스크립트 공식문서에서도 추천하는
const ODirection = {
Up: 0,
Down: 1,
Left: 2,
Right: 3
} as const;
type Direction = typeof ODirection[keyof typeof ODirection];
혹은
const ODirection = {
Up: "up",
Down: "down",
Left: "left",
Right: "right"
} as const;
type Direction = typeof ODirection[keyof typeof ODirection];
(참고: Don't use Enums in Typescript, they are very dangerous 😨 - DEV Community)
이걸 사용하는 게 나을 듯 하다!
추후 JS에 Enum이 공식적으로 추가되는 것을 기다리기 좋다는 말도 있다.