[Typescript] enum vs Union types

milkcoke·2022년 1월 26일
1

javascript

목록 보기
13/21
post-thumbnail

🎯 Goals

타입스크립트에서의

  • enum 의 용도를 알고 쓴다.
  • enum 을 사용해본다.
  • enum 사용시 체크포인트

enum 은 왜, 언제 쓰는가?

임의의 문자열이나 숫자를 사전 정의하여 개발자의 실수를 줄이고 코드의 가독성을 높이기 위해.

enum BLOOD_TYPE {
    A,
    B,
    AB,
    O
}

enum에 특이점이 있다고?

enum BLOOD_TYPE {
    A,
    B,
    AB,
    O
}
console.dir(BLOOD_TYPE);

// print
// { 
//	'0': 'A', 
//	'1': 'B', 
//	'2': 'AB', 
//	'3': 'O', 
//	A: 0, 
//	B: 1, 
//	AB: 2, 
// 	O: 3 
//}

모든 키값을 거꾸로 뒤집어 펼쳐놓은 모습이다.

사실 enum 은 Javascript 에 존재하지 않는 키워드로
트랜스파일시 IIFE 코드를 생성한다.
IIFE 는 Tree-shaking 대상에서 제외될 수 있다.
자세한 원리는 🔗 여기서 참고하시라.

enum 대신 as const

우리는 enum 키워드 없이 enum 을 사용할 것이다.
다음처럼

export const BLOOD_TABLE = {
    A: 0, // Default Number
    B: 1,
    AB: 2,
    O: 3
} as const;

이런 질문을 할 수도 있겠다. as const 는 또 뭐야?
예제를 통해 알아보자.

as const ❌

as const ✅

as const ❌ => Primitive type inference
as const ✅ => Literal type inference

즉, 정리 됐는가? Enum 을 함수의 파라미터로 넘길 때, 리터럴 상수 값으로 더 엄격하게 제한할 수 있다.
가령 위 예제에선 as const 없이 enum 을 사용하려 할 경우 어떤 숫자든 인자로 받아도 트랜스파일 전에 경고를 하지 않는다.

💡 as const는 리터럴 상수 처리를 위해 필요한 키워드다.

타입스크립트에서 const 키워드로 선언된 것들은 값이 아니라 타입을 강제하는 것이다. (명시적으로 선언한 값 자체를 타입으로 보는 것이다.)

Union Types

가장 권장하는 방법으로, js 로 트랜스파일링 후에도 Tree-shaking 이 일어난다.

Tree-shaking 은 사용하지 않는 코드를 삭제하는 기능이다.
예를들어 export 했지만 아무 데서도 import 하지 않은 모듈이나 사용하지 않는 코드를 삭제해서 번들 크기를 줄여준다.

이제는 keyoftypeof 를 통해 필요한 enum 속성을 정의해보자.

type BLOOD_TYPE_KEY = keyof typeof BLOOD_TABLE;
// "A" | "B" | "AB" | "O"

type BLOOD_SERIAL_NUMBER = typeof BLOOD_TABLE[BLOOD_TYPE_KEY]; 
// 0 | 1 | 2 | 3

keyof operator only takes an object and produces a string or numeric literal union of its keys

- Typescript docs

📝 결론

타입스크립트에서 enum 을 쓰고싶다면 Union Types 를 활용하라.

뇌비우고 쓰고싶다면 그냥 다음 코드 복사하자.

export const BLOOD_TABLE = {
    A: 0, // Default Number
    B: 1,
    AB: 2,
    O: 3
} as const;

/* 
    - as const 붙인 것과 안 붙인 것의 차이?
    일반 => Primitive type inference
    as const => Literal type inference
    👉🏻 Enum type 을 올바로 쓰고싶다면 as const 사용 권장.
 */

// keyof operator only takes an object and produces a string or numeric literal union of its keys
type BLOOD_TYPE_KEY = keyof typeof BLOOD_TABLE; // A, B, AB, O

export type BLOOD_SERIAL_NUMBER = typeof BLOOD_TABLE[BLOOD_TYPE_KEY]; // 0 | 1 | 2 | 3

부록 질문

const MAX = 10_000_000 | 20_000_000 as const;

// 여기서의 MAXTYPE 의 type 은?
type MAXTYPE = typeof MAX;

// 이게 될까?
const maxNum : MAXTYPE = 15_000_000;

🔗 Reference

profile
I'm still hungry

0개의 댓글