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

# 개요
Enum(열거형)은 타입이자 데이터로 각 멤버(Member)에 숫자나 문자 값을 부여합니다.
값의 범위가 일정하게 정해져 있는 경우, 객체나 배열 데이터 대신 사용하기에 좋습니다.
[열거]: 여러 가지 예나 사실을 낱낱이 죽 늘어놓음
1234567enum 이름 { 멤버1 = 값1, 멤버2 = 값2 } const member: 이름 = 이름.멤버1 // 값1 const value: 이름 = 값1
# 숫자
Enum 타입 멤버의 값으로는 주로 숫자(Number)를 사용합니다.
숫자는 Enum의 양방향 매핑을 지원하며, 명시적 또는 암시적으로 값을 할당할 수 있습니다.
# 명시적 할당
Enum 타입의 각 멤버에 =
(할당) 연산자를 사용해 값을 명시적으로 할당할 수 있습니다.
다음 예제에서 Week
Enum 타입은 Sun
부터 Sat
까지 총 7개의 멤버를 가지며 0
부터 6
까지 숫자가 명시적으로 할당되었습니다.
123456789enum 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)을 지원한다고 합니다.
12345678910111213// 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)됩니다.
1234567891011121314151617enum 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
을 더한 값이 자동으로 할당됩니다.
1234567891011121314151617enum 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)를 사용할 수도 있습니다.
다만, 문자 값은 양방향 매핑을 지원하지 않습니다.
123456789101112131415161718192021enum 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)
또한 문자 값을 하나라도 사용하는 경우, 모든 멤버는 명시적으로 초기화해야 합니다.
다음 예제에서 Fri
와 Sat
은 명시적 초기화가 없으므로 에러가 발생합니다.
123456789enum Week { Sun = '일', Mon = '월', Tue = '화', Wed = '수', Thu = '목', Fri, // Error - ts(1061) Sat // Error - ts(1061) }
# 숫자와 혼합
다음과 같이 Enum의 멤버에서 문자와 숫자 값을 혼합할 수도 있습니다.
하지만 타입의 일관성이 깨지고 코드의 가독성이 저하되므로 권장되는 사용법은 아닙니다.
123456789enum Week { Sun = '일', Mon = '월', Tue = '화', Wed = 3, Thu = 4, Fri = 5, Sat = 6 }
# const Enum
123456789101112enum 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
객체)가 생성됩니다.
12345678910111213"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
객체와 나머지 멤버는 생성되지 않는 것을 확인할 수 있습니다.
123456789101112const enum Week { Sun, Mon, Tue, Wed, Thu, Fri, Sat } console.log(Week.Sun) // 0 console.log(Week.Mon) // 1
123"use strict"; console.log(0 /* Week.Sun */); // 0 console.log(1 /* Week.Mon */); // 1
# 활용 예제
# 주문 상태
OrderStatus
Enum은 주문 접수부터 취소까지 총 5가지 상태를 나타냅니다.
그리고 주문 상태에 맞게 메시지를 반환하는 getOrderMessage
함수를 정의합니다.
이 함수는 status
매개변수로 OrderStatus.Shipped
이나 1
같은 주문 상태의 값을 받도록 타입을 지정합니다.
123456789101112131415161718192021export 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 '알 수 없는 상태입니다.' } }
12345678import { 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
)와 같이 각 상태를 명확하게 구분할 수 있습니다.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374// 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, // 네트워크 액세스 인증 필요 }
끝까지 읽어주셔서 감사합니다.
좋아요와 응원 댓글은 블로그 운영에 큰 힘이 됩니다!