
TypeScript 에서 enum 사용을 피하라는 영상이나 글을 종종 보게 된다.
다만 enum 이 꼭 나쁜 것일까...? 에 대해서는 아니라고 말하고 싶다.

as const: TypeScript 변수의 값을 절대로 바꾸지 못하도록 하는 type assertion 이다.
enum 의 단점enum Role {
ADMIN,
USER
}
// JavaScript 로 컴파일된 결과
var Role;
(function (Role) {
Role[Role["ADMIN"] = 0] = "ADMIN";
Role[Role["USER"] = 1] = "USER";
})(Role|| (Role = {}));
이를 JavaScript 로 더 보기쉽게 옮기자면, 다음과 같이 변한다.
그렇기 때문에 Object.values() 와 같은 메서드를 사용했을 때 0, 1 이 추가되어서 나온다.
const Role = {
ADMIN: 0,
0: "ADMIN",
USER: 1,
1: "USER",
};
["USER", "ADMIN", 0, 1]
다음과 같이 문자열을 할당하거나, const enum 을 사용한다면, 이러한 현상을 피할 수 있다.
다만 as const 라는 대안이 바로 보인다.
/// 문자열 할당
enum Role {
USER = "USER",
ADMIN = "ADMIN",
}
// JavaScript 로 컴파일된 결과
var Role;
(function (Role) {
Role["ADMIN"] = "ADMIN";
Role["USER"] = "USER";
})(Role || (Role = {}));
/// const enum
const enum Role {
USER,
ADMIN
}
// JavaScript 로 컴파일 될 때는 할당된 값으로 변환됨.
// 설정되지 않았을 때는 자동으로 USER = 0, ADMIN = 1, ...
// ["USER", "ADMIN"]
Object.values(Role)
꼭 key 의 값과 동일한 문자열일 필요는 없다.
enum Role {
ADMIN = "ADMIN",
USER = "USER",
}
function helloUser(name: string, role: Role): void {
switch (role) {
case Role.ADMIN: {
console.log(`Hello admin ${name}!`);
break;
}
case Role.USER: {
console.log(`Hello user ${name}`);
break;
}
}
}
// Argument of type '"ADMIN"' is not assignable to parameter of type 'Role'.
helloUser('John Doe', 'ADMIN');
helloUser('John doe', Role.ADMIN);
enum 을 사용한다면, Role.ADMIN 에 해당하는 'ADMIN' 을 바로 사용할 수 없으며, 항상 Role.ADMIN 으로 사용해야 한다.
as const 를 사용한다면, 'ADMIN' 을 바로 사용할 수 있다.
const Role = {
ADMIN: "ADMIN",
USER: "USER",
} as const;
type RoleType = keyof typeof Role;
function helloUser(name: string, role: RoleType): void {
switch (role) {
case Role.ADMIN: {
console.log(`Hello admin ${name}!`);
break;
}
case Role.USER: {
console.log(`Hello user ${name}`);
break;
}
}
}
helloUser('John Doe', 'ADMIN');
helloUser('John doe', Role.ADMIN);
다만 이런 단점들을 나열하다보면, enum 의 장점 또한 엿보인다.
enum 의 장점as const 를 사용한 예시를 보면, helloUser 에서 Role 를 사용하기 위해 RoleType 을 따로 만들어서 사용하는 것을 볼 수 있다.
하지만 enum 을 사용한 예시를 보면, 바로 Role 을 사용했다.
이와 같이 enum 은 as const 보다 타입 지원이 강력하고, 이는 개발자의 편의성과 직결된다.
enum 의 해당되는 값을 바로 넣을 수 없다는 점은, 오히려 명확한 인터페이스를 제공하고 실수를 방지하기 쉽다.
enum 은 처음에 설명했던 것과 같이, as const 에 비해 단점도 많다.
잘못 사용하면 예상치 못한 동작을 발생시킬 수도 있으며, 유연하지 않다.
as const 는 enum 에 비해 훨씬 유연하기 때문에, 외부 API 와의 호환성이 높다.
또한 const 의 확장이기 때문에 JavaScript 호환성도 뛰어나며, JSON 직렬화/역직렬화 에서 유연함이 빛을 발한다.
enum 은 트리 쉐이킹을 지원하긴 하지만, 사용하지 않는 속성은 번들에서 제거가 가능한 as const 와 달리 전체가 포함되거나, 제거된다.
TypeScript 의 enum 은 꼭 나쁘진 않다.
하지만 as const 가 enum 보다 더 유연하고, 확실한 동작을 하는 것은 사실이다.