TypeScript의 enum은 사용하지 않는 것이 좋다.

Minsun
Written by Minsun on
TypeScript의 enum은 사용하지 않는 것이 좋다.

프로젝트에 사용되는 상수를 주로 object 형태나 TypeScript의 enum으로 선언하여 사용하는 것을 선호하였다. enum의 경우 문자열 할당이 가능하여 좀더 명확한 의미를 이해할 수 있고 enum에 들어있는 값만을 사용해야 되기 때문에 개인적으로 enum을 더 선호하는 편이였다. 그러다 상수만을 정리해둔 파일을 정돈하다가 사용하고 있는 enum 형태에 대한 의문이 생겨 리서치를 하게 되었다.

enum이란?

enum은 열거형 변수로 정수를 하나로 합칠 때 편리한 기능이다. 임의의 숫자나 문자열을 할당할 수 있으며 하나의 유형으로 사용하여 버그를 줄일 수 있다.

//아무것도 할당하지 않는 경우 0부터 숫자가 매겨진다.
enum LANGUAGE {
  KO, //0
  US, //1
  JA //2
}

//임의의 숫자나 문자열을 할당할 수 있다.
enum LANGUAGE {
  KO = 'korea',
  US = 'us',
  JA = 'japan'
}

enum을 사용하면 Tree-shaking 되지 않는다.

Tree-shaking이란 사용하지 않는 코들르 삭제하는 기능을 말한다. 나무를 흔들면 죽은 잎사귀들이 떨어지는 모습에서 착안되어 이와 같이 부른다. Tree-shaking 기능을 통하여 export 했지만 아무데서도 import 되어 사용되지 않는 모듈이나 코드를 삭제하여 번들 크기를 줄여 페이지가 표시되는 시간을 단축시킬 수 있다.

enum은 TypeScript 자체적으로 구현되었기 때문에 TypeScript 컴파일러는 IIFE(즉시 실행 함수)를 포함한 코드를 생성한다. 그런데 Rollup과 같은 번들러는 IIFE를 사용하지 않는 코드라고 판단할 수 없어서 Tree-shaking 되지 않는다. 만약 export 되었지만 사용되지 않더라도 최종 번들에는 포함이 된다.

//typescript enum
export enum MOBILE_OS {
  IOS,
  ANDROID
}

//위의 타입스크립트 코드를 트랜스파일하면 아래와 같은 자바스크립트 코드가 생성된다.
export var MOBILE_OS;
(function (MOBILE_OS) {
    MOBILE_OS[MOBILE_OS["IOS"] = 0] = "IOS";
    MOBILE_OS[MOBILE_OS["ANDROID"] = 1] = "ANDROID";
})(MOBILE_OS || (MOBILE_OS = {}));

Union Types

위에서 언급된 enum의 문제를 해결하지 위해선 Union Types를 사용하면 된다.

//union types를 사용하여 작성된 typescript 코드
const LANGUAGE = {
  KO: 'korea',
  US: 'us',
  JA: 'japan'
} as const;
type LANGUAGE = typeof LANGUAGE[keyof typeof LANGUAGE];

//위의 코드를 트랜스파일된 자바스크립트 코드
const LANGUAGE = {
  KO: 'korea',
  US: 'us',
  JA: 'japan'
}

위와 같이 작성하면 TypeScript 코드에선 LANGUAGE에 정의한 타입에 대한 이점을 얻고 자바스크립트로 트랜스 파일해도 IIFE가 생성되지 않아 Tree-shaking을 할 수 있다.

const enum

TypeScript에서 const enum을 사용하면 enum과 거의 같다고 느낄 수 있다. 하지만 enum의 내용이 트랜스파일할 때 인라인으로 확장된다는 점이 있다. Tree-shaking면에서는 Union Types와 동일하게 사용하지 않으면 번들에 포함되지 않지만 babel로 트랜스파일 할 수 없고 TypeScript의 —isolatedModules가 활성화된 환경에선 큰 의미가 없다.

Minsun

Minsun

Developer | Traveler | Thinker

Comments

comments powered by Disqus