열거형을 사용하면 이름이 있는 상수들을 정의할 수 있습니다.
enum
키워드를 이용하여 정의할 수 있습니다.
Typescript는 숫자 및 문자열 기반 열거형을 모두 제공합니다.숫자 열거형 (Numeric enums)
enum Direction {
Up,
Down,
Left,
Right,
}
초기화 되지 않은 열거형의 첫번째 값은 '0'으로 시작합니다.
이 때, Up = 1
이라고, 값을 지정해 주면, 다음부터는 자동증가하여 Direction.Up
은 1
, Down
은 2
, Left
는 3
, Right
는 4
가 됩니다.
초기화가 되지 않은 열거형은 상수 또는 다른 상수 열거형의 멤버로 초기화된 숫자 열거형을 따라야할 필요가 있으며, 아래와 같은 경우는 허용되지 않습니다.
enum E {
A = getSomeValue(),
B, // 오류 ! A 는 상수로 초기화되지 않았으므로 B에는 초기화가 필요합니다.
}
아래의 코드처럼 중간 중간에 전혀 다른 값으로 초기화 시킬 경우,
그 다음의 값은 무조건 이전 값에서 +1 이 된 값을 지니게 됩니다.
즉, Down = 2
, Right = 6
이 됩니다.
enum Direction {
Up = 1,
Down,
Left = 5,
Right,
}
열거형의 이름을 사용하여 타입을 선언할 수 있습니다.
enum Response1 {
No = 0,
Yes = 1,
}
function respond(recipient: string, message: Response1): void {
// ...
}
respond("Princess Caroline", Response1.Yes)
각 열거형 멤버에는 constant 또는 computed 중 하나일 수 있는 값이 있습니다.
열거형 멤버는 상수 열거형 표현식으로 초기화됩니다.
1. 리터럴 열거 표현식 (기본적으로 문자 리터럴 또는 숫자 리터럴)
2. 이전에 정의된 상수 열거형 멤버 (다른 열거형에서 올 수 있음)에 대한 참조
3. 괄호로 묶인 상수 열거형 표현식
4. 상수 열거형 표현식에 적용된 +, -, ~ 단항 연산자 중 하나
5. +, -, *, /, %, <<, >>, >>>, &, |, ^ 바이너리 연산자에 사용된 상수 열거형 표현식
(상수 열거형 표현식이 NaN 또는 Infinity 로 평가되는 것은 컴파일 타임 에러입니다.)
enum FileAccess {
// 상수 멤버
None,
Read = 1 << 1,
Write = 1 << 2,
ReadWrite = Read | Write,
// 계산된 멤버
G = "123".length
}
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
문자 열거형은 자동 증가 동작을 하지 않지만, "직렬화(serialize)"하는 이점이 있습니다.
문자 열거형을 사용하면 열거형 멤버 자체의 이름과 독립적으로 코드가 실행될 때, 읽기 쉬운 값을 제공합니다.
숫자형 + 문자형 열거형을 말하지만,
JavaScript의 런타임 동작을 실제로 사용하려고 하지 않는 한 이렇게 하지 않는 것이 좋다고 합니다.
enum BooleanLikeHeterogeneousEnum {
No = 0,
Yes = "YES",
}
리터럴 열거형 멤버는 초기화된 값이 없거나 다음 값으로 초기화 된 값이 있는 상수 열거형 멤버입니다.
열거형의 모든 멤버가 리터럴 열거형 값을 가질 때, 일부 특수한 의미가 있습니다.
첫번째, 열거형 멤버도 타입이 된다는 것입니다.
예를 들어 특정 멤버는 열거형 멤버의 값만 가질 수 있습니다.
enum ShapeKind {
Circle,
Square,
}
interface Circle {
kind: ShapeKind.Circle;
radius: number;
}
interface Square {
kind: ShapeKind.Square;
sideLength: number;
}
let c: Circle = {
kind: ShapeKind.Square,
// ~~~~~~~~~~~~~~~~ 오류!
radius: 100,
}
두번째, 열거 타입 자체가 각 열거형 멤버의 합집합(union) 이 된다는 것입니다.
조합 열거형을 사용하는 타입 시스템이 열거형 자체에 존재하는 정확한 값들을 알고있다는 사실을 활용할 수 있습니다.
이 때문에 TypeScript는 값을 잘못 비교하는 버그를 잡을 수 있습니다.
enum E {
Foo,
Bar,
}
function f(x: E) {
if (x !== E.Foo || x !== E.Bar) {
// ~~~~~~~~~~~
// 오류! 연산자 '!==' 는 'E.Foo' 및 'E.Bar' 타입에 적용할 필요가 없습니다. 이미 E 타입은 Foo 와 Bar 만 존재하기 때문에!
}
}
열거형은 런타임에 존재하는 실제 객체입니다.
enum E {
X, Y, Z
}
실제로 함수에 전달 될 수 있습니다.
function f(obj: { X: number }) {
return obj.X;
}
// 작동합니다. 왜냐하면 `E` 는 숫자인 `X` 라는 속성을 가지고있기 떄문입니다.
f(E);
숫자 열거형 멤버는 열거형 값에서 열거형의 이름으로 역 매핑(reverse mapping) 을 받을 수 있습니다.
enum Color {
Red
}
let red = Color.Red;
let nameOfRed = Color[red]; // "Red"
이 생성된 코드에서 열거형은 전방향(forward) (name -> value) 매핑과 역방향(reverse) (value -> name) 매핑을 모두 저장하는 객체로 컴파일됩니다.
다른 열거형 멤버에 대한 참조는 항상 속성 접근으로 방출되며 결고 인라인(inline)되지 않습니다.
문자열 열거형 멤버는 역매핑을 생성하지 않습니다.
const
열거형 (const
enums)const
열거형은 상수 열거형 표현식만 사용할 수 있으며 (즉, 계산된 멤버를 가질 수 없습니다.), 일반 열거형과 달리 컴파일하는 동안 완전히 제거됩니다.const
열거형 멤버는 사용하는 사이트에서 인라인(inline)됩니다.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 */];
declare enum Enum {
A = 1,
B,
C = 2
}
declare
는 객체를 사용할 수 없고, 타입을 선언하는 경우에만 가능합니다.
(지금 공부한 것만으로는 declare에 대해 정확히 표현할 수 없을 것 같습니다. 좀 더 자세히 공부하고 난 후, 첨부하도록 하겠습니다.)
[enum과 const enum 의 차이][TS 8. enum vs const enum | FELog](https://jaeyeophan.github.io/2018/06/16/TS-8-enum-vs-const-enum/)
[enum을 사용하는 이유]
https://medium.com/@seungha_kim_IT/typescript-enum%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0-3b3ccd8e5552
[about declare]
https://stackoverflow.com/questions/28818849/how-do-the-different-enum-variants-work-in-typescript