TypeScript 핸드북 7 - Enum

Enums

enum을 사용하면 이름이 부여된 상수 집합을 정의할 수 있습니다. enum 타입은 enum 키워드를 사용하여 정의할 수 있습니다.

1
2
3
4
5
6
enum Direction {
Up = 1,
Down,
Left,
Right
}

enum의 본문은 0개 이상의 enum 멤버로 구성됩니다. enum 멤버는 관련된 숫자 값을 가지며 상수 또는 계산된 값 일 수 있습니다. enum 멤버는 다음과 같은 경우 상수로 간주됩니다.

  • 초기화 코드가 없고 앞의 enum 멤버가 상수입니다. 이 경우 현재 enum 멤버의 값은 이전 멤버의 값에 1을 더한 값이 됩니다. 이 규칙의 한 가지 예외는 enum의 첫 번째 요소입니다. 초기화가 없으면 값 0이 지정됩니다.

  • enum 멤버는 상수 enum expression으로 초기화됩니다. 상수 enum은 컴파일 타임에 완전히 평가할 수 있는 TypeScript expression의 하위 집합입니다. Expression이 다음 중 하나 일 경우 상수 enum 입니다.

    • 숫자 리터럴
    • 이전에 정의된 상수 enum 멤버 (다른 enum에서 정의할 수 있음)에 대한 참조. member가 동일한 enum에 정의된 경우 규정되지 않은 이름을 사용하여 참조할 수 있습니다.
    • 괄호로 묶인 상수 열거 expression
    • 상수 enum expression에 적용된 단항 연산자+,-,~
    • 이진 연산자 +, -, *, /, %, <<, >>, >>>, &, |, ^이 상수 enum expression의 피연산자로 사용되는 경우 NaN 또는 Infinity로 평가되면 컴파일 타임 오류입니다.

다른 모든 경우에 enum 멤버는 계산된 것으로 간주됩니다.

1
2
3
4
5
6
7
8
9
enum FileAccess {
// constant members
None,
Read = 1 << 1,
Write = 1 << 2,
ReadWrite = Read | Write,
// computed member
G = "123".length
}

enum은 런타임에 존재하는 실제 객체입니다. 그리고 enum 값에서 enum 이름으로 역 매핑을 유지하는 기능이 있습니다.

1
2
3
4
5
enum Enum {
A
}
let a = Enum.A;
let nameOfA = Enum[Enum.A]; // "A"

위 코드는 아래와 같이 컴파일 됩니다.

1
2
3
4
5
6
var Enum;
(function (Enum) {
Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
var a = Enum.A;
var nameOfA = Enum[Enum.A]; // "A"

생성된 코드에서 enum은 forward (name ->value) 매핑과 reverse (value ->name) 매핑을 모두 저장하는 객체로 컴파일됩니다. enum 멤버에 대한 참조는 항상 프로퍼티 접근으로 Emit되고 결코 Inline 되지 않습니다. 이러한 방법은 많은 경우에 완벽하게 유효한 해결책이 됩니다. 그러나 때로는 요구 사항이 더 엄격할 수 있습니다. enum 값에 액세스할 때 여분의 생성된 코드 및 추가 간접 비용을 지불하지 않으려면 상수 enum을 사용할 수 있습니다. 상수 enum은 enum 키워드 앞에 const 한정자를 사용하여 정의됩니다.

1
2
3
4
const enum Enum {
A = 1,
B = A * 2
}

const enum은 상수 enum Expression만 사용할 수 있고 일반 enum과 달리 컴파일 중에 완전히 제거됩니다. const enum 멤버는 사용 사이트에서 Inline됩니다. 이것은 상수 enum이 계산된 멤버들을 가질 수 없기 때문에 가능합니다.

1
2
3
4
5
6
7
8
const enum Directions {
Up,
Down,
Left,
Right
}
let directions = [Directions.Up, Directions.Down, Directions.Left, Directions.Right]

생성된 코드는 아래와 같습니다.

1
var directions = [0 /* Up */, 1 /* Down */, 2 /* Left */, 3 /* Right */];

Ambient enums

Ambient enum은 이미 존재하는 enum 타입의 형태를 기술하기 위해 사용됩니다.

1
2
3
4
5
declare enum Enum {
A = 1,
B,
C = 2
}

Ambient와 Non-ambient enum 사이의 중요한 차이점 중 하나는 일반적인 enum에서 초기화 코드가 없는 멤버는 상수 멤버로 간주된다는 것입니다. 상수 Ambient enum이 아닌경우, 초기화 코드를 가지지 않은 멤버는 계산된 것으로 간주됩니다.


이 내용은 나중에 참고하기 위해 제가 공부하며 정리한 내용입니다.
의역, 오역, 직역이 있을 수 있음을 알려드립니다.
This post is a translation of this original article [https://www.typescriptlang.org/docs/handbook/enums.html]

참고

공유하기