99

최근 30분간 동시 방문자 수를 표시합니다. (~)

최고 동시 방문자 수 -
어제: 0명 / 오늘: 0명

타입스크립트 Enum 타입 톺아보기

타입스크립트 Enum 타입 톺아보기

# 개요

Enum(열거형)은 타입이자 데이터로 각 멤버(Member)에 숫자나 문자 값을 부여합니다.
값의 범위가 일정하게 정해져 있는 경우, 객체나 배열 데이터 대신 사용하기에 좋습니다.

[열거]: 여러 가지 예나 사실을 낱낱이 죽 늘어놓음

TS
content_copy
1
2
3
4
5
6
7
enum 이름 { 멤버1 = 값1, 멤버2 = 값2 } const member: 이름 = 이름.멤버1 // 값1 const value: 이름 = 값1

# 숫자

Enum 타입 멤버의 값으로는 주로 숫자(Number)를 사용합니다.
숫자는 Enum의 양방향 매핑을 지원하며, 명시적 또는 암시적으로 값을 할당할 수 있습니다.

# 명시적 할당

Enum 타입의 각 멤버에 =(할당) 연산자를 사용해 값을 명시적으로 할당할 수 있습니다.
다음 예제에서 Week Enum 타입은 Sun부터 Sat까지 총 7개의 멤버를 가지며 0부터 6까지 숫자가 명시적으로 할당되었습니다.

TS
content_copy
1
2
3
4
5
6
7
8
9
enum Week { Sun = 0, Mon = 1, Tue = 2, Wed = 3, Thu = 4, Fri = 5, Sat = 6 }

Enum은 객체 데이터의 점 표기법(Dot Notation)처럼 멤버 이름으로 값에 접근하거나, 배열의 대괄호 표기법(Bracket Notation)처럼 멤버 이름이나 숫자로 값에 접근(Indexing)할 수 있습니다.
이를 양방향 매핑(Bidirectional Mapping) 또는 역방향 매핑(Reverse Mapping)을 지원한다고 합니다.

TS
content_copy
1
2
3
4
5
6
7
8
9
10
11
12
13
// Like, { Sun: 0, Mon: 1, Tue: 2, ... } console.log(Week.Sun) // 0 console.log(Week.Mon) // 1 console.log(Week.Tue) // 2 console.log(Week['Sun']) // 0 console.log(Week['Mon']) // 1 console.log(Week['Tue']) // 2 // Like, ['Sun', 'Mon', 'Tue', ...] console.log(Week[0]) // 'Sun' console.log(Week[1]) // 'Mon' console.log(Week[2]) // 'Tue'

# 암시적 할당

Enum 타입을 선언할 때 명시적으로 값을 할당하지 않으면, 자동으로 0부터 1씩 증가하는 숫자가 할당(Auto Incrementing)됩니다.

TS
content_copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
enum Week { Sun, Mon, Tue, Wed, Thu, Fri, Sat } console.log(Week.Sun) // 0 console.log(Week.Mon) // 1 console.log(Week.Tue) // 2 console.log(Week.Wed) // 3 console.log(Week.Thu) // 4 console.log(Week.Fri) // 5 console.log(Week.Sat) // 6

# 명시적 초기화

다음과 같이 할당 연산자(=)를 사용해 일부 멤버의 값을 명시적으로 초기화할 수 있습니다.
이때 값을 명시하지 않은 멤버는 이전 멤버의 값에 1을 더한 값이 자동으로 할당됩니다.

TS
content_copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
enum Week { Sun, Mon, Tue = 7, Wed = 10, Thu = 24, Fri, Sat } console.log(Week.Sun) // 0 console.log(Week.Mon) // 1 console.log(Week.Tue) // 7 console.log(Week.Wed) // 10 console.log(Week.Thu) // 24 console.log(Week.Fri) // 25 console.log(Week.Sat) // 26

# 문자

Enum 타입은 주로 숫자를 값으로 사용하지만, 문자(String)를 사용할 수도 있습니다.
다만, 문자 값은 양방향 매핑을 지원하지 않습니다.

TS
content_copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
enum Week { Sun = '일', Mon = '월', Tue = '화', Wed = '수', Thu = '목', Fri = '금', Sat = '토' } console.log(Week.Sun) // '일' console.log(Week.Mon) // '월' console.log(Week.Tue) // '화' console.log(Week.Wed) // '수' console.log(Week.Thu) // '목' console.log(Week.Fri) // '금' console.log(Week.Sat) // '토' // 양방향 매핑 지원 X console.log(Week[0]) // Error - ts(7053) console.log(Week['일']) // Error - ts(7053)

또한 문자 값을 하나라도 사용하는 경우, 모든 멤버는 명시적으로 초기화해야 합니다.
다음 예제에서 FriSat은 명시적 초기화가 없으므로 에러가 발생합니다.

TS
content_copy
1
2
3
4
5
6
7
8
9
enum Week { Sun = '일', Mon = '월', Tue = '화', Wed = '수', Thu = '목', Fri, // Error - ts(1061) Sat // Error - ts(1061) }

# 숫자와 혼합

다음과 같이 Enum의 멤버에서 문자와 숫자 값을 혼합할 수도 있습니다.
하지만 타입의 일관성이 깨지고 코드의 가독성이 저하되므로 권장되는 사용법은 아닙니다.

TS
content_copy
1
2
3
4
5
6
7
8
9
enum Week { Sun = '일', Mon = '월', Tue = '화', Wed = 3, Thu = 4, Fri = 5, Sat = 6 }

# const Enum

TS
content_copy
1
2
3
4
5
6
7
8
9
10
11
12
enum Week { Sun, Mon, Tue, Wed, Thu, Fri, Sat } console.log(Week.Sun) // 0 console.log(Week.Mon) // 1
변환 전

위 예제의 Enum 타입을 자바스크립트로 변환하면, 아래와 같이 Week["Sun"]으로 0이 할당되고, Week[0]으로 "Sun"이 할당되는 등의 양방향 매핑 객체(Week 객체)가 생성됩니다.

info

Week["Sun"] = 0의 반환은 0입니다.
따라서 Week[Week["Sun"] = 0]Week[0]과 같습니다.

JS
content_copy
1
2
3
4
5
6
7
8
9
10
11
12
13
"use strict"; var Week; (function (Week) { Week[Week["Sun"] = 0] = "Sun"; Week[Week["Mon"] = 1] = "Mon"; Week[Week["Tue"] = 2] = "Tue"; Week[Week["Wed"] = 3] = "Wed"; Week[Week["Thu"] = 4] = "Thu"; Week[Week["Fri"] = 5] = "Fri"; Week[Week["Sat"] = 6] = "Sat"; })(Week || (Week = {})); console.log(Week.Sun); // 0 console.log(Week.Mon); // 1
변환 후

만약 Enum 타입을 선언할 때 const 키워드를 앞에 추가하면, 타입을 변환할 때 Enum의 정의는 제거되고 사용하는 코드만 인라인(Inline) 생성됩니다.
이는 런타임에서 불필요한 코드를 제거하므로 성능 최적화에 도움이 될 수 있습니다.

다음 예제와 같이 const 키워드와 함께 선언하는 Week Enum 타입을 변환하면, 콘솔에 출력하는(실제로 사용하는) 멤버의 값만 생성되고 Week 객체와 나머지 멤버는 생성되지 않는 것을 확인할 수 있습니다.

TS
content_copy
1
2
3
4
5
6
7
8
9
10
11
12
const enum Week { Sun, Mon, Tue, Wed, Thu, Fri, Sat } console.log(Week.Sun) // 0 console.log(Week.Mon) // 1
변환 전
JS
content_copy
1
2
3
"use strict"; console.log(0 /* Week.Sun */); // 0 console.log(1 /* Week.Mon */); // 1
변환 후

# 활용 예제

# 주문 상태

OrderStatus Enum은 주문 접수부터 취소까지 총 5가지 상태를 나타냅니다.
그리고 주문 상태에 맞게 메시지를 반환하는 getOrderMessage 함수를 정의합니다.
이 함수는 status 매개변수로 OrderStatus.Shipped이나 1 같은 주문 상태의 값을 받도록 타입을 지정합니다.

/src/utils/order.ts
TS
content_copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
export enum OrderStatus { Pending, // 주문 접수 Shipped, // 배송 중 Delivered, // 배송 완료 Confirmed, // 구매 확정 Cancelled // 취소 } export function getOrderMessage(status: OrderStatus) { switch (status) { case OrderStatus.Pending: return '주문이 접수되었습니다.' case OrderStatus.Shipped: return '제품이 배송 중입니다.' case OrderStatus.Delivered: return '제품 배송이 완료되었습니다.' case OrderStatus.Cancelled: return '주문이 취소되었습니다.' default: return '알 수 없는 상태입니다.' } }
/src/views/message.ts
TS
content_copy
1
2
3
4
5
6
7
8
import { OrderStatus, getOrderMessage } from '@/utils/order' console.log(getOrderMessage(OrderStatus.Shipped)) // '제품이 배송 중입니다.' console.log(getOrderMessage(OrderStatus.Delivered)) // '제품 배송이 완료되었습니다.' console.log(getOrderMessage(0)) // '주문이 접수되었습니다.' console.log(getOrderMessage(4)) // '주문이 취소되었습니다.' console.log(OrderStatus.Pending) // 0 console.log(OrderStatus.Confirmed) // 4

# HTTP 상태 코드

HTTP 상태 코드를 값으로 하는 Enum을 정의해, HttpStatusCode.OK(200)와 같이 각 상태를 명확하게 구분할 수 있습니다.

TS
content_copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Status export enum HttpStatusCode { // 정보 Continue = 100, // 지금까지의 상태가 괜찮으며, 클라이언트가 요청을 계속하거나 완료 시 무시 가능 SwitchingProtocols = 101, // 서버가 클라이언트의 Upgrade 요청에 따라 프로토콜 변경 Processing = 102, // 서버가 요청을 수신 및 처리 중이나 응답 미완료 (WebDAV) EarlyHints = 103, // Link 헤더와 함께 사용, 서버 응답 준비 중 사용자 에이전트 사전 로딩 시작 // 성공 Ok = 200, // 요청 성공, HTTP 메소드에 따라 의미 상이 (GET, HEAD, PUT, POST, TRACE) Created = 201, // 요청 성공, 새로운 리소스 생성 (주로 POST 또는 일부 PUT) Accepted = 202, // 요청 수신, 처리 불가 또는 비동기 응답 (다른 프로세스 또는 배치 처리용) NonAuthoritativeInformation = 203, // 메타 정보가 오리진 서버와 다르며 로컬/서드 파티에서 수집 NoContent = 204, // 콘텐츠 없음, 헤더는 유의미하며 캐시된 헤더 업데이트 가능 ResetContent = 205, // 요청 완료 후 문서 뷰 리셋 요청 PartialContent = 206, // 범위 헤더로 분할 다운로드 요청 시 사용 MultiStatus = 207, // 여러 리소스의 다양한 상태 코드 정보 전달 (WebDAV) AlreadyReported = 208, // 동일 컬렉션 내부 멤버 반복 열거 방지 (WebDAV) ImUsed = 226, // GET 요청 완료, 인스턴스 조작 적용 (HTTP Delta encoding) // 리다이렉션 MultipleChoices = 300, // 하나 이상의 응답 가능, 사용자 에이전트가 선택해야 함 MovedPermanently = 301, // 리소스의 URI 영구 변경, 새로운 URI 제공 가능 Found = 302, // 리소스의 URI 일시적 변경, 동일 URI로 요청 유지 SeeOther = 303, // 다른 URI에서 GET 요청으로 리소스 획득 NotModified = 304, // 캐시용, 응답이 수정되지 않아 캐시된 버전 사용 가능 UseProxy = 305, // 프록시를 통한 접속 필요 (지원 중단) Unused = 306, // 더 이상 사용되지 않으며 예약됨 TemporaryRedirect = 307, // 다른 URI로 동일 메소드 요청, 302와 유사하나 메소드 변경 금지 PermanentRedirect = 308, // 영구적으로 다른 URI로 이동, 메소드 변경 금지 // 클라이언트 에러 BadRequest = 400, // 잘못된 문법으로 요청 이해 불가 Unauthorized = 401, // 클라이언트 인증 필요 (비인증 상태) PaymentRequired = 402, // 디지털 결제용 예약, 현재 미사용 Forbidden = 403, // 클라이언트 권한 없음, 서버는 클라이언트 신원 인지 NotFound = 404, // 요청한 리소스 없음, API 또는 숨김 리소스 가능 MethodNotAllowed = 405, // 서버가 메소드 인지하나 사용 불가 NotAcceptable = 406, // 사용자 에이전트 규격에 맞는 콘텐츠 없음 ProxyAuthenticationRequired = 407, // 프록시 인증 필요 RequestTimeout = 408, // 요청 시간 초과, 서버가 연결 종료 원함 Conflict = 409, // 요청이 서버 상태와 충돌 Gone = 410, // 리소스 영구 삭제, 캐시 및 링크 제거 기대 LengthRequired = 411, // Content-Length 헤더 미정의로 요청 거절 PreconditionFailed = 412, // 클라이언트 전제조건이 서버와 부적합 PayloadTooLarge = 413, // 요청 엔티티가 서버 한계 초과 UriTooLong = 414, // 요청 URI가 서버 처리 한계 초과 UnsupportedMediaType = 415, // 지원하지 않는 미디어 포맷 RequestedRangeNotSatisfiable = 416, // 요청한 범위가 리소스 크기 벗어남 ExpectationFailed = 417, // Expect 헤더의 예상 부적합 ImATeapot = 418, // 커피를 찻주전자에 끓이는 요청 거절 MisdirectedRequest = 421, // 요청 URI로 응답 생성 불가 UnprocessableEntity = 422, // 문법 오류로 요청 처리 불가 (WebDAV) Locked = 423, // 리소스 접근 잠김 (WebDAV) FailedDependency = 424, // 이전 요청 실패로 현재 요청 실패 (WebDAV) UpgradeRequired = 426, // 다른 프로토콜로 업그레이드 필요 PreconditionRequired = 428, // 조건적 요청 필요, 업데이트 상실 방지 TooManyRequests = 429, // 지정 시간 내 과도한 요청 (rate limiting) RequestHeaderFieldsTooLarge = 431, // 헤더 필드 크기 초과로 요청 거절 UnavailableForLegalReasons = 451, // 법적 이유로 리소스 접근 불가 // 서버 에러 InternalServerError = 500, // 서버가 처리 방법 모르는 상황 발생 NotImplemented = 501, // 요청 방법 지원 안 함, GET과 HEAD는 제외 BadGateway = 502, // 게이트웨이에서 잘못된 응답 수신 ServiceUnavailable = 503, // 서버 과부하 또는 유지보수로 요청 처리 불가 GatewayTimeout = 504, // 게이트웨이 역할 서버가 적시 응답 불가 HttpVersionNotSupported = 505, // 요청 HTTP 버전 지원 안 함 VariantAlsoNegotiates = 506, // 투명 콘텐츠 협상이 순환 참조로 이어짐 InsufficientStorage = 507, // 가변 리소스 구성 오류로 협상 종료 불가 LoopDetected = 508, // 요청 처리 중 무한 루프 감지 (WebDAV) NotExtended = 510, // 서버의 요청 이행을 위해 추가 확장 필요 NetworkAuthenticationRequired = 511, // 네트워크 액세스 인증 필요 }