https://blog.logrocket.com/extend-enums-typescript/
해당 글을 번역한 정도 수준에 그치는 글입니다.
enum MyFavorite {
Apple = 'apple',
Banana = 'banana',
Pear = 'pear',
StrawBerry = 'strawberry'
}
enum YouFavorite {
Apple = 'apple',
Banana = 'banana',
Pear = 'pear',
Mango = 'mango'
}
enum WeFavorite {
Apple = 'apple',
Banan = 'banana',
Pear = 'pear',
Orange = 'orange'
}
다음과 같은 enum
3개가 있다고 가정하자. 그렇다면 당연히 우리는 공통적인 부분을 분리하고 싶어진다.
enum Fruit {
Apple = 'apple',
Banana = 'banana',
Pear = 'pear'
}
enum MyFavorite extends Fruit {
StrawBerry = 'strawberry'
}
enum YouFavorite extends Fruit {
Mango = 'mango'
}
enum WeFavorite extends Fruit {
Orange = 'orange'
}
type
을 상속받을 때 처럼 extends
키워드를 사용한다면 어떨까. 해당 코드는 에러가 발생한다. 타입스크립트에서 enum에 대한 extends
키워드의 사용을 제공하지 않기 때문이다. 더 나아가 타입스크립트는 enum
을 상속하거나 받는 언어적 기능을 제공하지 않는다.
enum Door {
Open = "open",
Closed = "closed",
Ajar = "ajar"
}
enum DoorFrame {
Missing = "noDoor"
}
type DoorState = Door | DoorFrame;
let door: DoorState;
door = Door.Ajar
console.log(door) // 'ajar'
door = DoorFrame.Missing
console.log(door) // 'noDoor'
다음 예제처럼 union type
을 사용하는 방법이다. 이를 통해 특정 변수의 타입을 여러 개의 enum
을 통해 제한할 수 있다. 하지만 이 방법은 단순히 두 개의 enum
타입을 사용하는 방법이다. 두 개 enum
을 합친 것의 값을 사용할 수는 없다.
enum Door {
Open = "open",
Closed = "closed",
Ajar = "ajar"
}
enum DoorFrame {
Missing = "noDoor"
}
type DoorState = Door | DoorFrame;
DoorState.Open // Error! DoorState는 타입
enum Move {
LEFT = 'Left',
RIGHT = 'Right',
FORWARD = 'Forward',
BACKWARD = 'Backward'
}
const myMove = {
...Move,
JUMP: 'Jump'
}
이 방식은 값에 대한 사용이 가능하다. 하지만 좋은 방법은 아니다. Move
라는 enum
객체와 myMove
라는 객체의 병합이 런타임에서 이루어지기 때문이다. (이전 union type
을 사용하는 방식은 컴파일/트랜스파일 타임에서 이루어짐)
보통 enum을 사용할 때 나는 그 값을 사용하는 경우가 훨씬 많은 것 같다. 때문에 첫번째 방법을 사용할 수는 없을 것 같다. 때문에 아예 공통 부분을 분리하려는 노력을 시도하지 않거나 흐린 눈하고 두번째 방법을 사용하는 것이...ㅎ
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
기술적으로 하나의 enum
내부에 string
, number
두 타입의 값이 혼재할 수 있지만 이렇게 사용하는 것은 좋지 않은 방법이다. (enum의 값으로 들어올 수 있는 타입은 string
, number
두 가지) (코드 자체에 대한 이해를 어렵게 만들기 때문. 정말로 특별한 이유가 있다면 이런 식의 사용도 가능)
enum DayOfWeek {
Sunday,
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday
};
function isItTheWeekend(day: DayOfWeek) {
switch (day) {
case DayOfWeek.Sunday:
case DayOfWeek.Saturday:
return true;
default:
return false;
}
}
개발을 진행하다보면 다음과 같이 enum
을 switch
구문의 조건으로 활용하는 경우들이 생긴다. 이러한 구문은 다음과 같은 문제들을 가진다.
enum
의 특징인 역참조로 인한 문제가 발생할 수 있다.console.log(isItTheWeekend(DayOfWeek.Monday)); // false
console.log(isItTheWeekend(2)); // false
enum
자체가 수정되는 경우 enum
과 함수(isItTheWeekand
) 두 곳에서의 수정이 필요해진다.
metadata
와 코드의 불필요한 분리다.
const DayOfWeek = {
Sunday: {
id: 0,
apply() { return true }
},
Monday: {
id: 1,
apply() { return false }
},
// ...
}
다음과 같이 하나의 객체에서 enum과 함수를 동시에 관리하는 것이 관리의 주체를 줄이는 방법일 수 있다.
https://blog.logrocket.com/extend-enums-typescript/
https://blog.logrocket.com/why-typescript-enums-suck/