ts-for-jsdev
  • 자바스크립트 개발자를 위한 타입스크립트
  • 들어가며
  • 01 타입스크립트 소개
    • 1.0 들어가며
    • 1.1 정적 타입 분석
    • 1.2 왜 타입스크립트인가
    • 1.3 타입스크립트의 구성요소
    • 1.4 타입스크립트의 역사
  • 02 ECMAScript
    • 2.0 ECMAScript
    • 2.1 블록 수준 스코프
      • 2.1.1 let을 이용한 선언
      • 2.2.2 const를 이용한 선언
      • 2.2.3 스코프 베스트 프랙티스
    • 2.2 객체와 배열
      • 2.2.1 비구조화 할당
      • 2.2.2 나머지 연산자와 전개 연산자
      • 2.2.3 객체 리터럴 변경사항
    • 2.3 함수
      • 2.3.1 기본 매개변수
      • 2.3.2 화살표 함수
    • 2.4 템플릿 리터럴
      • 2.4.1 멀티라인 문자열
      • 2.4.2 문자열 치환
    • 2.5 원소 순회
      • 2.5.1 forEach 메소드
      • 2.5.2 for-of 문법
      • 2.5.3 이터레이터 프로토콜
      • 2.5.4 이터러블 프로토콜
    • 2.6 비동기 처리
      • 2.6.1 프로미스
      • 2.6.2 Async / Await
    • 2.7 맺으며
  • 03 타입스크립트 기초 문법
    • 3.0 타입스크립트 기초 문법
    • 3.1 기본 타입
    • 3.2 배열과 튜플
    • 3.3 객체
    • 3.4 타입 별칭
    • 3.5 함수
    • 3.6 제너릭
    • 3.7 유니온 타입
    • 3.8 인터섹션 타입
    • 3.9 열거형
  • 04 인터페이스와 클래스
    • 4.0 들어가며
    • 4.1 인터페이스 기초
    • 4.2 색인 가능 타입
    • 4.3 인터페이스 확장
    • 4.4 클래스
    • 4.5 클래스 확장
    • 4.6 클래스 심화
      • 4.6.1 스태틱 멤버
      • 4.6.2 접근 제어자
      • 4.6.3 접근자
      • 4.6.4 추상 클래스
    • 4.7 인터페이스와 클래스의 관계
    • 4.8 맺으며
  • 05 타입의 호환성
    • 5.0 들어가며
    • 5.1 기본 타입의 호환성
    • 5.2 객체 타입의 호환성
    • 5.3 함수 타입의 호환성
    • 5.4 클래스의 호환성
    • 5.5 제너릭의 호환성
    • 5.6 열거형의 호환성
    • 5.7 맺으며
  • 06 타입 시스템 심화
    • 6.0 들어가며
    • 6.1 타입 좁히기
    • 6.2 타입 추론
    • 6.3 타입 단언
    • 6.4 집합으로서의 타입
    • 6.5 서로소 유니온 타입
    • 6.6 맺으며
  • 07 고급 타입
    • 들어가며 (7월 2일 공개)
  • 08 모듈과 네임스페이스
    • 들어가며 (7월 16일 공개)
  • 09 실제 프로젝트에서 사용하기
    • 들어가며 (7월 30일 공개)
  • 10 유용한 라이브러리 소개
    • 들어가며 (8월 13일 공개)
    • 맺으며
  • 부록 II : 자바스크립트 언어 생태계
    • ECMAScript 언어 표준과 TC39
    • TC39 프로세스
    • 실제 예시 - Array.prototype.includes
    • 타입스크립트와 ECMAScript
Powered by GitBook
On this page
  • 숫자 열거형(Numeric Enum)
  • 멤버 값 초기화
  • 문자열 열거형(String Enum)
  • 상수 멤버와 계산된 멤버
  • 런타임에서의 열거형
  • 유니온 열거형
  • 유니온 타입을 이용한 열거형 표현
  1. 03 타입스크립트 기초 문법

3.9 열거형

유한한 경우의 수를 갖는 값의 집합을 표현하기 위해 사용하는 열거형(enum) 타입에 대해 배운다.

숫자 열거형(Numeric Enum)

숫자 열거형은 number 타입 값에 기반한 열거형이다. 만약 열거형을 정의하며 멤버의 값을 초기화하지 않을 경우, 해당 멤버의 값은 0부터 순차적으로 증가하는 숫자 값을 갖는다. 예를 들어 아래 예제 두 예제는 동일하게 동작한다.

enum Direction {
  East,
  West,
  South,
  North
}
enum ExplicitDirection {
  East = 0,
  West = 1,
  South = 2,
  North = 3
}

이렇게 정의한 열거형의 멤버에는 객체의 속성에 접근하는 것과 동일한 방식으로 접근할 수 있다. 어떤 열거형 Enum의 모든 멤버는 Enum 타입을 갖는다.

const south: Direction = Direction.South;
console.log(south); // 2

멤버 값 초기화

0부터 시작되는 자동 초기화에 의존하는 대신, 각 멤버의 값을 직접 초기화 할 수 있다.

enum InitializedDirection {
  East = 2,
  West = 4,
  South = 8,
  North = 16
}

만약 초기화 되지 않은 멤버가 섞여있다면, 그 멤버의 값은 이전에 초기화된 멤버의 값으로부터 순차적으로 증가해서 결정된다.

enum InitializedDirection2 {
  East = 3,
  West /* 4 */,
  South = 7,
  North /* 8 */
}

문자열 열거형(String Enum)

number 타입 값 대신 string 타입 값을 사용해서 멤버 값을 초기화하는 것도 가능하다.

enum Direction {
  East = 'EAST',
  West = 'WEST',
  South = 'SOUTH',
  North = 'NORTH'
}

문자열 열거형은 숫자 열거형과 다음 부분을 제외하고는 많은 부분 동일하다.

  • 문자열을 ‘자동 증가’ 시킨다는 개념은 성립하지 않는다. 따라서 문자열 멤버 이후로 정의된 모든 멤버는 명시적으로 초기화되어야 한다.

  • 숫자 열거형과 달리, 문자열 열거형이 컴파일된 자바스크립트 코드에는 값 → 키 의 역방향 매핑(reverse mapping)이 존재하지 않는다.

한 열거형에서 숫자 멤버와 문자열 멤버를 모두 사용하는 식의 이형 열거형(Heterogeneous Enum)도 문법 상 허용은 된다. 하지만 이형 열거형을 사용해 큰 이득을 얻을 수 있는 경우는 드물고, 대부분의 경우 혼란을 불러 올 수 있어 권장되지 않는다.

상수 멤버와 계산된 멤버

지금까지 다룬 열거형의 멤버는 모두 명시적이든, 암시적든 컴파일 타임에 알 수 있는 상수값으로 초기화 되었다. 이런 열거형 멤버를 상수 멤버(constant member)라 부른다.

한 편, 런타임에 결정되는 값을 열거형의 멤버 값으로 사용할 수도 있다. 이런 멤버를 계산된 멤버(computed member)라고 부른다. 계산된 멤버의 값은 실제로 코드를 실행시켜봐야만 알 수 있으므로, 계산된 멤버 뒤에 오는 멤버는 반드시 초기화되어야 한다는 점에 유의하라.

function getAnswer() {
  return 42;
}
enum SpecialNumbers {
  Answer = getAnswer(),
  Mystery // error TS1061: Enum member must have initializer.
}

런타임에서의 열거형

기본적으로 아래와 같은 타입스크립트 코드에서의 열거형 정의 및 접근은

enum Direction {
  East,
  West,
  South,
  North
}
const east: Direction = Direction.East;

아래와 같은 자바스크립트 코드로 컴파일 된다.

var Direction;
(function (Direction) {
    Direction[Direction["East"] = 0] = "East";
    Direction[Direction["West"] = 1] = "West";
    Direction[Direction["South"] = 2] = "South";
    Direction[Direction["North"] = 3] = "North";
})(Direction || (Direction = {}));
var east = Direction.East;

이 코드를 보면 두 가지 일이 일어나고 있음을 확인할 수 있다.

  • 식별자에 키 → 값으로의 매핑이 정의된다. (Direction["EAST"] = 0)

  • 식별자에 값 → 키로의 역방향 매핑이 정의된다. (Direction[Direction["East"] = 0] = "East")

문자열 열거형의 경우 앞서 언급한대로 역방향 매핑이 존재하지 않는다. 아래의 문자열 열거형은

enum Direction {
  East = 'EAST',
  West = 'WEST',
  South = 'SOUTH',
  North = 'NORTH'
}

아래 자바스크립트 코드로 컴파일된다.

var Direction;
(function (Direction) {
    Direction["East"] = "EAST";
    Direction["West"] = "WEST";
    Direction["South"] = "SOUTH";
    Direction["North"] = "NORTH";
})(Direction || (Direction = {}));

컴파일된 코드로부터 열거형 멤버에 접근 할 때 실제로 코드가 실행될 때에도 객체 속성 접근이 발생함을 알 수 있다. 이 오버헤드는 대부분의 경우 무시 가능할 수준이다. 그럼에도 성능 향상을 꾀하고 싶다면 const 열거형을 사용할 수 있다.

모든 멤버가 컴파일 시간에 알려진 상수값인 열거형의 경우 enum 키워드 대신 const enum 키워드를 이용해 정의할 수 있다. 이렇게 정의한 열거형의 구조는 컴파일 과정에서 완전히 사라지고, 멤버의 값은 상수값으로 대체된다. 아래의 예제를 보자.

const enum ConstEnum {
  A,
  B = 2,
  C = B * 2,
  D = -C,
}
console.log(ConstEnum.A);

위 코드는 아래 자바스크립트 코드로 컴파일된다.

console.log(0 /* A */);

주석을 제외하고는 열거형의 원래 구조에 대한 어떠한 정보도 남아있지 않고, 상수값으로 대체되어 있음을 확인할 수 있다.

유니온 열거형

열거형의 모든 멤버가 아래 경우 중 하나에 해당하는 열거형을 유니온 열거형(union enum)이라 부른다.

  • 암시적으로 초기화 된 값 (값이 표기되지 않음)

  • 문자열 리터럴

  • 숫자 리터럴

예를 들어 아래 ShapeKind 열거형은 유니온 열거형이다.

enum ShapeKind {
  Circle,
  Triangle = 3,
  Square
}

유니온 열거형의 멤버는 값인 동시에 타입이 된다. 따라서 예를 들어 아래와 같은 코드를 작성할 수 있다.

type Circle = {
  kind: ShapeKind.Circle;
  radius: number;
}
type Triangle = {
  kind: ShapeKind.Triangle;
  maxAngle: number;
}
type Square = {
  kind: ShapeKind.Square;
  maxLength: number;
}
type Shape = Circle | Triangle | Square;

또한 컴파일러는 유니온 열거형의 특징으로부터 컴파일 타임에 추가적인 검사를 시행할 수 있다. 이에 대해서는 추후 타입 좁히기(type narrowing)에 대해 다룰 때 함께 다룬다.

유니온 타입을 이용한 열거형 표현

타입스크립트는 숫자, 문자열 그리고 불리언 값을 타입으로 사용하는 리터럴 타입(literal type)을 지원한다. 리터럴 타입을 이용해 단 하나의 값만을 갖는 타입을 정의할 수 있다.

const answer: 42 = 42;
const wrongAnswer: 42 = 24; // error TS2322: Type '24' is not assignable to type '42'.

이 때 리터럴 타입과 유니온 타입을 조합해 열거형과 유사한 타입을 만들 수 있다.

type Direction = 'EAST' | 'WEST' | 'SOUTH' | 'NORTH';
const east: Direction = 'EAST';
const center: Direction = 'CENTER'; // error TS2322: Type '"CENTER"' is not assignable to type 'Direction'.
Previous3.8 인터섹션 타입Next4.0 들어가며

Last updated 6 years ago