Enum Types

열거형 (Enums)

숫자 열거형 (Numeric enums)

enum Direction {
    Up = 1,
    Down,
    Left,
    Right,
}

원한다면, 전부 초기화 하지 않기도 가능

enum Direction {
    Up,
    Down,
    Left,
    Right,
}

열거형 사용법

enum Response {
    No = 0,
    Yes = 1,
}

function respond(recipient: string, message: Response): void {
    // ...
}

respond("Princess Caroline", Response.Yes)

즉 아래 방식은 사용 불가능

enum E {
    A = getSomeValue(),
    B, // 오류! 앞에 나온 A가 계산된 멤버이므로 초기화가 필요합니다.
}

문자열 열거형 (String enums)

enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT",
}

예시)

enum NumericMembership {
		Normal = 1,
		Silver,
		Gold,
		VIP,
}

enum StringMembership {
		Normal = "NORMAL",
		Silver = "SILVER"
		Gold = "GOLD",
		VIP = "VIP",
}

console.log(NumericMembership.Gold); // 2
console.log(NumericMembership[NumericMembership.Gold]) // Gold - reverse mapping
console.log(StringMembership.Gold); // GOLD

이종 열거형 (Heterogeneous enums)

enum BooleanLikeHeterogeneousEnum {
    No = 0,
    Yes = "YES",
}

계산된 멤버와 상수 멤버 (Computed and constant members)

열거형의 멤버는 상수이거나 계산된 값일 수 있다.

열거형의 멤버는 아래의 경우 상수로 간주

위 경우 이외의 다른 모든 경우 열거형 멤버는 계산된 것

enum FileAccess {
    // 상수 멤버
    None,
    Read    = 1 << 1,
    Write   = 1 << 2,
    ReadWrite  = Read | Write,
    // 계산된 멤버
    G = "123".length
}

유니언 열거형과 열거형 멤버 타입 (Union enums and enum member types)

열거형의 모든 멤버가 리터럴 열거형 값을 가지면 특별한 의미로 쓰이게 됨

첫째

열거형 멤버를 타입처럼 사용할 수 있게 됨

enum ShapeKind {
    Circle,
    Square,
}

interface Circle {
    kind: ShapeKind.Circle;
    radius: number;
}

interface Square {
    kind: ShapeKind.Square;
    sideLength: number;
}

let c: Circle = {
    kind: ShapeKind.Square, // 오류! 'ShapeKind.Circle' 타입에 'ShapeKind.Square' 타입을 할당할 수 없습니다.
    radius: 100,
}

둘째

enum E {
    Foo,
    Bar,
}

function f(x: E) {
    if (x !== E.Foo || x !== E.Bar) {
        //             ~~~~~~~~~~~
        // 에러! E 타입은 Foo, Bar 둘 중 하나이기 때문에 이 조건은 항상 true를 반환합니다.
    }
}

런타임에서 열거형 (Enums at runtime)

enum E {
    X, Y, Z
}
function f(obj: { X: number }) {
    return obj.X;
}

// E가 X라는 숫자 프로퍼티를 가지고 있기 때문에 동작하는 코드입니다.
f(E);

컴파일 시점에서 열거형 (Enums at compile time)

enum LogLevel {
    ERROR, WARN, INFO, DEBUG
}

/**
 * 이것은 아래와 동일합니다. :
 * type LogLevelStrings = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
 */
type LogLevelStrings = keyof typeof LogLevel;

function printImportant(key: LogLevelStrings, message: string) {
    const num = LogLevel[key];
    if (num <= LogLevel.WARN) {
       console.log('Log level key is: ', key);
       console.log('Log level value is: ', num);
       console.log('Log level message is: ', message);
    }
}
printImportant('ERROR', 'This is a message');

역 매핑 (Reverse mappings)

enum Enum {
    A
}
let a = Enum.A;
let nameOfA = Enum[a]; // "A"
var Enum;
(function (Enum) {
    Enum[Enum["A"] = 0] = "A";
})(Enum || (Enum = {}));
var a = Enum.A;
var nameOfA = Enum[a]; // "A"

const 열거형 (const enums)

const enum Enum {
    A = 1,
    B = A * 2
}
const enum Directions {
    Up,
    Down,
    Left,
    Right
}

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

Ambient 열거형 (Ambient enums)

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

ambient 열거형과 비-ambient 열거형의 가장 큰 차이점