All enums Are Union enums
TypeScript가 처음으로 Enum을 도입했을 때, 그것들은 동일한 타입을 가진 일련의 숫자 상수에 불과했습니다.
enum E {
Foo = 10,
Bar = 20,
}
E.Foo와 E.Bar에 대한 특별한 것은 타입 E를 기대하는 것에 할당할 수 있다는 것뿐이었습니다.
그 외에는 거의 숫자였습니다.
function takeValue(e: E) {}
takeValue(E.Foo); // 작동
takeValue(123); // 오류!
TypeScript 2.0에서 Enum 리터럴 타입이 도입될 때까지 Enum이 조금 더 특별해지지 않았습니다.
Enum 리터럴 타입은 각 Enum 멤버에게 자체 타입을 부여하고, Enum 자체를 각 멤버 타입의 Union으로
변환했습니다.
또한 Enum의 타입 중 일부만 참조하고 그 타입을 좁힐 수 있게 해주었습니다.
// Color는 Red | Orange | Yellow | Green | Blue | Violet의 유니온과 같습니다.
enum Color {
Red, Orange, Yellow, Green, Blue, /* Indigo */, Violet
}
// 각 열거형 멤버는 참조할 수 있는 자체 타입을 가집니다!
type PrimaryColor = Color.Red | Color.Green | Color.Blue;
function isPrimaryColor(c: Color): c is PrimaryColor {
// 리터럴 타입을 좁히면 버그를 잡을 수 있습니다.
// TypeScript는 여기서 오류를 발생시키는데
// 'Color.Red'를 'Color.Green'과 비교하게 됩니다.
// ||를 사용하려고 했지만 실수로 &&를 썼습니다.
return c === Color.Red && c === Color.Green && c === Color.Blue;
}
각 Enum 멤버에게 자체 타입을 부여하는 것의 문제점 중 하나는 그 타입이 어느 정도 멤버의 실제 값과 연관되어
있다는 것이었습니다.
경우에 따라서는 그 값을 계산할 수 없습니다.
예를 들어, Enum 멤버는 함수 호출로 초기화될 수 있습니다.
enum E {
Blah = Math.random()
}
TypeScript 5.0은 계산된 멤버 각각에 대해 고유한 타입을 생성하여 모든 enum을 union enum type으로
만들어 줍니다.
이렇게 하면 모든 enum type이 좁혀지고 멤버를 타입으로 참조할 수 있게 됩니다.
이 변경에 대한 자세한 내용은 GitHub에서 세부 사항을 확인할 수 있습니다.