Enums

장유진·2022년 6월 28일
1

TypeScript

목록 보기
9/14

Enum은 JavaScript에서 타입 확장이 되지 않았다. Enum을 사용하면 이름을 가진 상수 집합을 만들 수 있고 TypeScript는 numeric enum과 string-based enum을 제공한다.

Numeric Enums

enum 키워드를 사용하여 enum을 생성할 수 있다. enum이 초기화되지 않는다면 차례로 0부터 1씩 증가하는 값을 가지며 초기화된다면 초기화 된 값부터 차례로 1씩 증가한 값을 가진다. 아래 예제에서는 Up이 1로 초기화되었으므로 자동으로 Down은 2, Left는 3, Right은 4의 값을 가진다.

initializer가 없는 enum 멤버는 첫 번째에 위치하거나 숫자 상수로 초기화된 멤버 뒤에 위치해야 한다.

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

enum을 사용하려면 enum 자체의 property를 그대로 사용하고 enum의 이름을 사용하여 타입으로 선언하면 된다.

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

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

respond("Princess Caroline", UserResponse.Yes);

String Enums

string enum은 각 멤버들이 string literal 혹은 다른 string enum 멤버로 초기화되어야 한다.

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

Heterogeneous enums

numeric 멤버와 string 멤버를 섞어서 사용할 수도 있다. 하지만 enum의 용도가 명확하게 보이지 않기 때문에 사용을 추천하지는 않는다.

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

Computed and Constant members

각 enum 멤버들은 constant 또는 computed 값을 가지게 된다.

constant인 경우

  • enum의 첫 번째 멤버이고 initializer가 없는 경우(0으로 초기화되는 경우)

  • initializer가 없으며 앞의 enum 멤버의 값이 숫자 상수인 경우

  • 상수로 초기화된 경우
    => 상수: literal 표현(number or string), 다른 constant enum 멤버를 참조한 경우, 괄호 안의 상수 표현, 상수로 연산을 한 경우

computed인 경우

  • 나머지 모든 경우는 computed이다.
enum FileAccess {
  // constant members
  None,
  Read = 1 << 1,
  Write = 1 << 2,
  ReadWrite = Read | Write,
  // computed member
  G = "123".length,
}

Union Enums and Enum member types

enum 멤버들이 전부 literal 값을 가지고 있다면

  • enum 멤버들이 타입으로도 사용 가능하다.

  • enum 타입 자체가 enum 멤버들의 union이 된다.

Enums at Runtime

enum은 런타임에 존재하는 실제 객체이다.

enum E {
  X,
  Y,
  Z,
}

function f(obj: { X: number }) {
  return obj.X;
}

// Works, since 'E' has a property named 'X' which is a number.
f(E);

Enums at Compile time

enum이 런타임에 존재하는 실제 객체이긴 하지만 keyof 키워드가 일반 객체와는 다르게 작동한다. 따라서 enum key를 string으로 표현하는 타입을 얻기 위해서는 keyof typeof 키워드를 사용해야 한다.

enum LogLevel {
  ERROR,
  WARN,
  INFO,
  DEBUG,
}

/**
 * This is equivalent to:
 * type LogLevelStrings = 'ERROR' | 'WARN' | 'INFO' | 'DEBUG';
 */
type LogLevelStrings = keyof typeof LogLevel;

Reverse mappings

보통 enum 멤버 이름에서 값으로 mapping을 하지만, numeric enum의 경우(string enum은 안됨)에는 반대로 멤버 값에서 이름으로 mapping이 가능하다.

enum Enum {
  A,
}

let a = Enum.A;
let nameOfA = Enum[a]; // "A"

Const enum

const enum은 상수 값만 enum으로 사용하고 일반 enum과 달리 컴파일 하는 동안 완전히 사라진다. const 키워드를 enum 선언 앞에 붙여 생성할 수 있다.

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

let directions = [
  Direction.Up,
  Direction.Down,
  Direction.Left,
  Direction.Right,
];

위의 코드가 컴파일을 거치면 아래와 같은 코드가 된다.

"use strict";
let directions = [
    0 /* Up */,
    1 /* Down */,
    2 /* Left */,
    3 /* Right */,
];
profile
프론트엔드 개발자

0개의 댓글