enum Direction {
North = 1,
South,
East,
West,
}
enum Direction {
Up = 5,
}
console.log(Direction.North);
console.log(NumericEnums2["0"]); // reverse mapping
Direction.North
처럼 프로퍼티로 모든 멤버에게 접근 가능하다.Object.keys(Direction)
사용 시 숫자까지 key 값에 담기므로 원치 않는 결과가 나올수도 있다.enum Direction {
North = "NORTH",
South = "SOUTH",
East = "EAST",
West = "WEST,
}
Tree Shaking이 되지 않는다. (아래에서 자세히 설명할 예정)
JS로 변환된 후 용량이 커진다.
숫자 열거형은 예기치 못한 문제를 일으킬 수 있다.
enum Direction {
North,
South,
East,
West,
}
declare function moveToward(direction: Direction): void;
moveToward(100); // 에러가 발생하지 않는다.
enum 간의 값 비교가 불가능하다.
enum Direction1 {
North = "NORTH",
South = "SOUTH",
East = "EAST",
West = "WEST,
}
enum Direction2 {
North = "NORTH",
South = "SOUTH",
East = "EAST",
West = "WEST,
}
위처럼 완전히 동일한 값을 가지는 enum이라고 하더라도 둘 사이의 값을 직접 비교하려 하면 아래와 같이 에러가 발생한다.
타입 추론
let LET = "let"; // string 타입으로 추론됨
const CONST = "const"; // "const" 타입으로 추론됨
let LET = "let" as const; // "let" 타입으로 추론됨
🤔 하지만 그냥 const를 쓰면 되는 것 아닌가..?
🔅 객체에 대한 Const Assertion
사실 위의 예시는 단순히 let으로 선언된 변수를 const로 수정하기만 해도 된다.
as const가 유용하게 사용되는 용례는 따로 있는데, 바로 특정 Object의 Value를 상수화할 때이다.
JS의 Object(객체, 배열, ...)는 원래 가변적인 데이터 값을 저장하기 위해 탄생했기 때문에
Const로 객체를 선언하더라도 특정 Key 값에 오는 Value를 고정시킬 수 없었다.
const object = {
first: "first",
two: "two",
};
이를 해결하기 위해 사용할 수 있는 것이 as const!
객체의 개별 키 값에 대해 설정해주기
const object = {
first: "first" as const,
two: "two",
};
객체 전체를 상수화하기
const object = {
first: "first",
two: "two",
} as const;
JS로 변환 후 enum에 비해 적은 용량을 차지한다.
Tree Shaking이 된다.
정확한 범위 지정이 가능하므로, enum과 달리 코드를 통해 결과물을 명확히 파악할 수 있다.
const Direction = {
North: 0,
South: 1,
East: 2,
West: 3,
} as const;
declare function moveToward(direction: Direction): void;
moveToward(100);
// 에러: '100' 형식의 인수는 'Values<{ readonly North: 0; readonly South: 1; readonly East: 2; readonly West: 3; }>' 형식의 매개 변수에 할당될 수 없습니다.
특징 | enum | as const |
---|---|---|
key에 의미있는 값을 부여할 수 있는가? | ⭕ | ⭕ |
type 지정을 하지 않아도 바로 사용할 수 있는가? | ⭕ | ❌ |
오타를 방지할 수 있는가? | ⭕ | ❌ |
key, value 순회에 용이한가? | ⭕ | ⭕ |
양방향 매핑이 가능한가? | ⭕ | ❌ |
Tree Shaking이 잘 되는가? | ❌ | ⭕ |
JS로 변환 시 용량 | 많음 | 적음 |
🍃 Tree Shaking
JS 변환 시 enum
enum Direction {
North = "NORTH",
South = "SOUTH",
East = "EAST",
West = "WEST,
}
"use strict";
var Direction;
(function (Direction) {
Direction["NORTH"] = "North";
Direction["SOUTH"] = "South";
Direction["EAST"] = "East";
Direction["WEST"] = "West";
})(Direction || (Direction = {}));
const enum
const enum Direction {
North = "NORTH",
South = "SOUTH",
East = "EAST",
West = "WEST",
}
const South = Direction.South;
// 변환 후
const South = "SOUTH";
해결책
as const를 쓰자
const Direction = {
North = "NORTH",
South = "SOUTH",
East = "EAST",
West = "WEST",
} as const;
type Direction = (typeof Direction)[keyof typeof Direction];
for (const d of Object.values(Direction)) {
console.log(d);
}
as const가 없었다면 object의 value 값이 string 타입으로 추론된다.
하지만 as const 사용 시 각각의 명시된 문자열 자체로 타입이 지정된다.
JS로 변환 시 enum과 달리 사라진다!
이처럼 union type과 as const를 사용하면 Tree Shaking 문제가 해결된다.
enum
as const