<aside> 💡 타입스크립트에서 열거형 대신 as const와 union type을 사용해야 하는 이유를 알아본다.

</aside>

열거형이란

많은 언어가 동일한 네임스페이스 아래서 관련 있는 값들을 묶기 위해 열거형이라는 기능을 지원한다. TypeScript는 enum 키워드로 열거형을 지원한다.

enum Direction {
	Up,
	Down,
	Left,
	Right
}

enum은 TypeScript의 기능이므로 JavaScrpt에서는 다음과 같이 작성하곤 한다.

const Direction = {
	UP: 'up',
	DOWN: 'down',
	LEFT: 'left',
	RIGHT: 'right'
};

열거형은 언제 사용하는가?

열거형은 (1) magic number, magic string을 상수로 관리하기 위해, 혹은 (2) 파라미터 타입으로 지정하기 위해 사용한다.

console.log(Direction.Up);	// (1) 상수 관리

const move = (direction: Direction) => console.log(direction);	// (2) 파라미터 타입 지정

그런데 열거형을 사용하면 몇 가지 문제가 있다. 어떤 문제가 있고, 대안은 무엇인지 알아본다.

enum의 문제

1. 사용되지 않는 enum은 Tree-shaking되지 않는다.

<aside> 💡 Tree-shaking이란 자바스크립트 코드를 번들할 때 사용하지 않는 코드를 삭제하는 것을 의미한다. Tree-shaking을 통해 자바스크립트 번들의 크기를 줄일 수 있다.

</aside>

열거형으로 작성된 위 Direction을 자바스크립트로 **트랜스파일(transpile)**하면 다음과 같다.

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 = {}));

열거형이 타입스크립트의 기능이기 때문에 자바스크립트에 존재하지 않고, 그래서 타입스크립트 컴파일러는 IIFE(Immediately Invoked Function Expression; 즉시 실행 함수)로 열거형을 트랜스파일한다. 그런데 Rollup과 같은 번들러는 IIFE를 사용하지 않는 코드로 판단할 수 없다. 즉, 열거형은 Tree-shaking할 수 없다.

이 문제를 피하기 위해서는 열거형을 const로 지정하면 된다. 하지만 const enum을 사용하는데에는 문제가 있다. 아래의 [const enum의 문제] 참고

2. 숫자 열거형은 type-safe하지 않다.

type-safe하다면 컴파일 시점에 오류를 일으킨다. 그러나 숫자 열거형은 type-safe하지 않아 유효하지 않은 숫자값에도 오류를 일으키지 않는다. 아래를 보자.