TypeScript

TypeScript에서 enum 사용하기: const enum vs as const 객체

citron031 2024. 4. 1. 00:23

TypeScript에서 열거형(enum)은 선호되지 않는다.

어째서일까?

 

TypeScript에서 열거형의 데이터를 표현하는 방법은 여러 가지가 있지만, 최신 버전의 TypeScript에서는 as const 객체를 사용하는 것이 일반적이다.

 

다만, 다른 언어에서 많이 사용되는 enum 방식의 사용은 공식문서에서도 추천되지 않는데,

 

이번 글에서는 이 두 가지 방법의 차이와 각각의 장단점을 알아보고 어째서 enum이 추천되지 않는 방식인지 알아보았다.

const enum과 일반 enum의 차이

🙌 enum을 표현하는데도 그냥 enum과 const enum이 존재하며 차이점이 있다.

 

일반 enum은 컴파일된 JavaScript 코드에서도 그대로 존재하며(번들링 사이즈 증가), reverse mapping을 지원한다.

하지만 const enum은 컴파일 과정에서 코드가 완전히 제거되며 단방향 mapping만 지원한다.

 

// 일반 enum
enum Direction {
  Up = 0,
  Down = 1,
  Left = 2,
  Right = 3
}

// 컴파일된 JavaScript 코드에서는 다음과 같이 변환됩니다.
var Direction;
(function (Direction) {
  Direction[Direction["Up"] = 0] = "Up";
  Direction[Direction["Down"] = 1] = "Down";
  Direction[Direction["Left"] = 2] = "Left";
  Direction[Direction["Right"] = 3] = "Right";
})(Direction || (Direction = {}));

 

번들링된 자바스크립트 파일 크기의 증가는 네트워크 사용량을 높이기 때문에 비용을 증가시킨다.

enum은 번들링 사이즈를 증가시키기에 별로 좋은 선택지는 아니다.

 

그렇다면, const enum은 자바스크립트 코드가 남지 않기 때문에 as const 대신에 사용해도 괜찮지 않을까?
하지만, const enum에는 Const enum pitfalls 문제가 있다.

(const enum은 inline으로 코드가 사용되기 때문에 d.ts에 쓰는 등 여러곳에 사용 시 문제가 발생할 수 있다)

 

as const 객체를 이용한 enum 흉내 (공식문서에서도 이 방법을 추천한다 👍)

 

const enum 대신 as const 객체를 사용하여 enum과 유사한 효과를 낼 수 있다.

// as const 객체를 이용한 enum 흉내

const DirectionValues = {
  Up: 0,
  Down: 1,
  Left: 2,
  Right: 3
} as const;

type DirectionKeys = keyof typeof DirectionValues; // Up Down Left Right

type Direction = typeof DirectionValues[DirectionKeys]; // 0 1 2 3

 

 

🫢 타입스크립트 V5 이하에서는 enum에 버그가 존재한다.

버전 4.9.5에서는 예정되지 않은 값이 할당될 수 있다

 

위의 문제는 타입스크립트 버전 5에서 해결되었다.

 

5.0.4에서는  Type '-2000' is not assignable to type 'Direction'. 에러가 발생한다

 

const enum과 as const 객체의 장단점

  • enum: reverse mapping을 지원한다. 하지만 번들 사이즈를 증가시키고, 숫자나 문자열의 값만 표현할 수 있다. 그리고 enum은 자바스크립트로 컴파일된 후 즉시 실행 함수로 구현되기 때문에, Tree-Shaking이 되지 않는다.
  • const enum: 번들 사이즈를 줄일 수 있지만, 사용 시 여러 문제가 발생할 수 있습니다.
  • as const 객체: 더 짧고 컴파일 시 용량이 적으며, 양방향 매핑이 필요하지 않은 경우에 적합하다. boolean, 객체, 배열 등 다양한 타입을 프로퍼티 값으로 할당할 수 있다.

결론

enum을 사용할 때는 const enum보다는 as const 객체를 사용하는 것이 더 권장된다.

그렇지만, 양방향 매핑이 필요한 경우에는 enum을 고려할 수 있다.

 

이렇게 TypeScript에서 enum을 사용하는 방법과 그 특징에 대해 알아보았다.

정답이 정해진 것이 아니니, 필요한 타입 작성 방식을 판단해서 적절하게 코딩하자.

 

그래도 한줄 요약을 해보자면, 최신 자바스크립트에서는 as const를 사용하여 객체 타입을 표현할 수 있기 때문에 enum을 사용할 필요가 없다!

 

🧀 참고 자료

https://dev.to/maafaishal/you-might-not-need-typescript-enum-1f4n
https://www.typescriptlang.org/ko/docs/handbook/enums.html#objects-vs-enums
https://xpectation.tistory.com/218#const%--enum%EC%-D%--%--%EC%--%B-%EC%-E%--
https://www.typescriptlang.org/docs/handbook/enums.html#const-enum-pitfalls

 

Handbook - Enums

How TypeScript enums work

www.typescriptlang.org

 

Handbook - Enums

How TypeScript enums work

www.typescriptlang.org

 

You might not need TypeScript Enum

In TypeScript, there is a feature called Enum which is not a type-level extension of JavaScript....

dev.to