TypeScript의 enum은 관련된 상수 집합에 이름과 타입을 함께 주는 문법이다. 다른 TS 타입과 달리 런타임 객체로 컴파일되어 남는다. 요즘 프런트엔드에서는 같은 일을 as const 객체와 유니언 타입으로 하는 경우가 많다.
enum Direction { Up, Down }
// 컴파일 결과: IIFE + 양방향 매핑
// Direction[Direction["Up"] = 0] = "Up" → Direction.Up === 0, Direction[0] === "Up"
const STATUS = { Pending: 'PENDING', Success: 'SUCCESS' } as const
type Status = (typeof STATUS)[keyof typeof STATUS] // 'PENDING' | 'SUCCESS'- 숫자 enum은 역방향 매핑(Reverse Mapping)까지 생성하고, 아무 숫자나 들어가는 구멍이 있다. 쓴다면 문자열 enum이 디버깅과 서버 통신에 낫다
- 트리 셰이킹에 불리하다. enum은 IIFE(Immediately Invoked Function Expression)로 객체를 만드는 실행 코드라, 번들러가 부수 효과 가능성을 의심해 통째로 남기기 쉽다.
as const객체는 평범한 리터럴이라 분석이 쉽고 타입은 컴파일 때 사라진다(트리 셰이킹) const enum: 사용처에 값을 인라인해서 객체가 안 남는다. 하지만 파일 단위로 변환하는 도구(Babel, esbuild,isolatedModules)는 다른 파일의 값을 몰라 인라인하지 못하고 일반 enum처럼 다루거나,.d.ts에 선언된 const enum은 아예 쓰지 못하게 한다. 라이브러리 배포에도 위험하다(verbatimModuleSyntax와 import type)- enum이 어울리는 곳: 백엔드나 공통 라이브러리처럼 런타임 객체(
Object.values)가 필요하고 값 집합이 고정된 도메인 개념(주문 상태, 권한)
상수 객체에서 타입을 뽑는 문법은 매핑된 타입과 keyof, 이름 붙은 상수의 가치는 매직 넘버와 설명 상수, 문자열 규칙을 타입으로 만드는 방법은 템플릿 리터럴 타입.