열거형 ( Enum )

Eunji Park·2022년 7월 27일
0

TypeScript

목록 보기
6/18
post-thumbnail
post-custom-banner

✓ 열거형 ( Enum )

Enum을 활용하여 의미있는 상수 자료를 정의할 수 있다.

Key 값에 할당하며 순서가 없는 집합이자 자료구조이다.

사용방법은 enum 키워드와 PascalCase 조합을 생성한다.

또한, 계산된 값을 사용할 수 있다.

Enum은 TypeScript에서 제공하는 기능이고 JavaScript에 없는 문법이지만,

컴파일 후 JavaScript로 결과물이 즉시 실행 함수 형태로 남는다.

그 이유는 계산된 값으로 사용할 수 있기 때문이다.

반면 Interface는 컴파일 후 결과물이 남지 않는다.

// Enum
enum Prize {
  Gold = 100,
  Silver, // 101 : 숫자형 열거
  Bronze  // 102
}

// Interface
interface Inter {
  name: 'name'
}

// console.log(Inter.name) //--> 출력 불가 (Javascript 값으로 취급되지 않기 때문) 


// 객체 형태로 출력
console.log(Prize)
/* 결과
{ 
  "100" ; "Gold" , 
  "101" ; "Silver" , 
  "102" ; "Bronze" , 
  "Gold" ; "100" , 
  "Silver" ; "101" , 
  "Bronze" ; "102" 
}
*/

// 접근
console.log(Prize.Gold)     // 100
console.log(Prize['Gold'])  // 100

✓ 숫자형

아무 숫자도 할당하지 않으면 0부터 1씩 증가하면서 자동을 숫자가 할당된다.

enum Prize {
  Gold,   // 0
  Silver, // 1
  Bronze  // 2
}

시작하는 값만 할당해주면 자동으로 1씩 증가하면서 숫자가 할당된다.

enum Prize {
  Gold,   // 0
  Silver, // 1
  Bronze  // 2
}

간격이 1이 아니도록 할당하려면 하나하나 직접 할당해 주어야 한다.

enum Prize {
  Gold,   // 0
  Silver, // 1
  Bronze  // 2
}

✓ 문자형

문자형 열거는 각 요소의 값을 문자열로 초기화해야 한다.

문자형 열거는 숫자형 열거와 동작 방식이 다르다.

문자형 열거는 값이 자동으로 증가하지 않는다.

이외에도 리버스 매핑과의 차이도 존재한다.

enum Prize {
  Gold = "Gold",
  Silver = "Silver",
  Bronze = "Bronze"
}

console.log(Prize);
/* 결과
{
  Gold = "Gold",
  Silver = "Silver",
  Bronze = "Bronze"
}
*/

console.log(Prize.Silver);  // Silver
console.log(Prize[Bronze]); // Bronze

✓ 혼합형

앞서 살펴본 숫자형, 문자형 열거와 다르게 복합적인 혼합형 열거도 사용할 수 있다.

문자형과 동일하게 초기화해서 혼합형 열거를 만들 수 있다. ( 그러나, 추천하는 형태는 아님 )

enum Dummy {
  First = 0,
  Silver = 'Silver',
}

enum BoolLikeEnum {
  No = 0,
  Yes = 'YES',
}

✓ 리버스 매핑

리버스 매핑은 "역방향 찾기" 이다.

숫자형 열거 같은 경우 Key와 Value를 역으로 매핑할 수 있다.

단, 문자형 열거는 불가하다.

// --- 숫자형 열거 --- //
enum Order {
  First = 1,
  Second = 2,
  Third = 3,
}

console.log(Order)
/* 결과 )
   숫자형 열겨 Order는 Reverse Mapping을 지원한다.
{
  "First" : 1,
  "Second" : 2,
  "Third" : 3,
  1 : "First",
  2 : "Second",
  3 : "Third"
}
*/

const firstVal = Order.First           // 순방향 조회
const keyOfFirstVal = Order[firstVal]  // 역방향 조회

console.log(firstVal)  // 1
console.log(keyOfFirstVal)  // "First"



// --- 문자형 열거 --- //

enum OrderStr {
  First = 'First',
  Second = 'Second',
  Third = 'Third',
}

console.log(OrderStr)
/* 결과 )
   문자형 열겨 OrderStr는 Reverse Mapping을 지원하지 않는다.
{
  First = 'First',
  Second = 'Second',
  Third = 'Third',
}
*/

✓ const 열거

기본적으로 열거형은 불안전한 접근을 허용한다.

const 열거는 바로 이 점을 보완하기 위해 만들어진 안전한 열거형이다.

const 열거는 enum 앞에 const 키워드를 명시하여 사용한다.

const 열거는 컴파일 후 제거되기 때문에 JavaScript 코드를 생성하지 않는다.

때문에 다른 열거형을 활용한 것보다 더 가벼운 앱을 만들 수 있다는 장점이 있다.

기본 열거형

enum Desk {
    Color = 'White',
    Width = 1400,
}

Desk.Color   // "White"

// 존재하지 않는 열거형에 접근하기
Desk.Height     // Property 'Height' does not exist on type 'typeof Desk'
Desk['Height']  // Cannot find name 'Height' --> 넓은 범위의 any 타입으로 인정되어버릴 수 있다.

const 열거형

const enum Desk {
    Color = 'White',
    Width = 1400,
}

Desk.Color  // "White"


// const 열거형은 불안전한 접근을 허용하지 않으므로 Error 메시지가 동일하게 나타난다.
// typeof 로 비교하는 것이 좀더 안전하게 비교할 수 있는 방법이다.
// 그 이유는 그저 이름을 찾이 못하는 것과 typeof로 결과를 알려주는 것에 대한 차이가 있기 때문이다.
Desk.Height    // Property 'Height' does not exist on type 'typeof Desk'
Desk['Height'] // Property 'Height' does not exist on type 'typeof Desk'

✓ 열거형 활용

열거형이란 런타임에 존재하는 실제 객체이다.

keyof , keyof typeof 와 조합하여 활용할 수 있다.

 enum Language {
    TypeScript = 'TS',
    JavaScript = 'JS',
    Java = 'JAVA',
    Ruby = 'RB',
}

type Lang = 'TS' | 'JS'  // type alias

function getLang(langcode: string) {
  console.log(langcode);
}

getLang('아무 언어');  // X
getLang('Python');   // X
getLang('TS');

Example

// 숫자, 문자, 복합 타입
const enum Language {
    TypeScript = 'TS',
    JavaScript = 'JS',
    Java = 'JAVA',
    Ruby = 'RB',
}

const Language2 = {
    TypeScript: 'TS',
    JavaScript: 'JS',
    Java: 'JAVA',
    Ruby: 'RB',
} as const

type LangCode = keyof typeof Language
// 위와 아래가 같다
type LangCode2 = "TypeScript" | "JavaScript" | "Java" | "Ruby"

function getLang(langCode: LangCode) {
    console.log(langCode)
}
post-custom-banner

0개의 댓글