oris9

[Typescript] Enum 타입에 대해 알아보자 (단점, 주의사항, const enum) 본문

카테고리 없음

[Typescript] Enum 타입에 대해 알아보자 (단점, 주의사항, const enum)

oris9 2024. 5. 23. 09:54

 

짧게 요약 정리를 위쪽에서 하고 자세한 단점에 대한 내용은 아래 추가글로 정리해보려고한다

일단 개념이 필요하신 분들은 위에만 읽고 넘어가셔도 좋을 것 같다 

이 단점은 tree-shaking , 즉 번들링과정에서 사용하지 않는 코드를 제거함에 대한 문제를 담고있다

 

 

 

타입스크립트에서의 Enum은,

enum 숫자형이넘 {
  숫자형 = 1,
  숫자 = 2,
}

enum 문자열이넘 {
  문자열 = "foo",
  문자 = "foooooot",
}

과 같이 사용할 수 있다.

이넘은 이렇게 어떠한 숫자나 문자, 상수 집합을 의미하는 데이터 타입이고,

여러 개의 상수를 묶어서 관리할때 사용하게된다!

가독성이 좋고 유지관리가 편하지만 유연성은 떨어진다는 특징이 있다. ( -> 한번 선언하고 나면 수정이 어렵다)

 

숫자형이넘은 모든 값이 명시적으로 초기화 되지 않아도, 자동적으로 값이 할당되는 특징을 가지고 있다.

(기본적으로 증가되는 숫자값을 가지게 된다, 모든 값이 초기화되지 않으면 0, 1, 2, 3 ...
만약 처음 값이 6이라면 6, 7, 8, 9. ...
문자형이넘은 모두 명시적으로 초기화가 필수로 되어야한다!)

또한 숫자형 이넘만 `역매핑`이라는 특별한 기능이 지원되는데, 이 자동 초기화 기능때문에 가능한 것이다.

//역매핑, 리버스매핑
enum Enum {
  A;
}
let a = Enum.A;      // 0
let keyName = Enum[a];    // A

 

하지만 enum 방식은 TS에서 JS로 변환되는 트랜스파일링 후, 번들링 과정에서 최적화문제가 발생할 수 있다.

이를 해결하기 위해서 enum을 선언할때 앞에 const를 붙여 해결할 수 있다.

const enum 방식으로 선언해주면,

결과물의 코드양이 줄어들게 된다.

(하지만 const 방식은 속성 값 정의 방식을 사용할 수 없고, 항상 속성에 고정 값만 넣어주어야 한다는 주의점이 있으니 알아두자 ! )

 

번들러가 tree-shaking을 지원한다 ( 고려해야하는 상황이라면 )
Union type > const enum 또는 string일 경우 const enum, number가 들어갈 경우 union을 사용하거나 해서 조절

( 2020년 Line 블로그에서는 번들성능관점에서 Union Types > const enum > enum 순으로 권장한다 )

** Union Type (합집합, A ∪ B) :   type Marvel = "IronMan" | "Hulk";

 

 

어떻게 변환되는지 궁금하다면,,, 

const enum으로 선언하면 왜 괜찮은지 궁금하다면,,, 왜 const enum시에 속성에 고정 값만 넣어줘야하는 지 궁금하다면,,,

아래까지 읽어주세요

 

 

enum은 ts에서 자체적으로 구현했기 때문에 코드를 트랜스파일하면 아래와 같은 코드가 된다. 

export enum MOBILE_OS {
  IOS,
  ANDROID
}

// 문자열을 할당한 경우
export enum MOBILE_OS {
  IOS = 'iOS',
  ANDROID = 'Android'
}

<<< ts
---------------- 트랜스파일링 -------------------
>>> js

export var MOBILE_OS;
(function (MOBILE_OS) {                      // !!!!!!!!  IIFE(즉시 실행 함수)
    MOBILE_OS[MOBILE_OS["IOS"] = 0] = "IOS";
    MOBILE_OS[MOBILE_OS["ANDROID"] = 1] = "ANDROID";
})(MOBILE_OS || (MOBILE_OS = {}));

// 문자열을 할당한 경우
export var MOBILE_OS;
(function (MOBILE_OS) {
    MOBILE_OS["IOS"] = "iOS";
    MOBILE_OS["ANDROID"] = "Android";
})(MOBILE_OS || (MOBILE_OS = {}));

잘 보이라고 주석을 달아놓은 것과 같이..

즉시실행함수를 만들어 enum을 구현하게 된다. 

그런데 다양한 번들러들은 (2020년 라인블로그에서는 Rollup과 같은 번들러라고 소개하고 있다! - 번들러에 대해서는 아직 많이 몰라서 다른 블로그 글에 의존해서 적는다)  IIFE를 '사용하지 않는 코드'라고 판단할 수 없어서 Tree-shaking ( ** 사용하지 않는 코드를 제거하는 부분, 죽은 잎 떨구기) 이 되지 않는다고 한다. 

실제로 저 코드가 사용되지 않는다고 하더라도 최종 번들에 포함되게 되는 것이다. 

 

-- > 최근 글을 더 찾아보니 번들러의 종류나 버전, 아니면 interface안에 enum을 조건으로 넣는다거나 하는 다양한 상황에 따라서 IIFE가 생길 수도 있고 생기지 않을 수도 있는 것 같다. 무조건 생긴다고 생각하면 안될거같고, 최근 번들링도구라고 해서 무조건 안생긴다고 생각해서도 안될듯..

 

const enum은

const enum MOBILE_OS {
    IOS = 'iOS',
    ANDROID = 'Android',
}
const ios = MOBILE_OS.IOS

<<< ts
---------------- 트랜스파일링 ----------------
>>> js

const ios = "iOS"

 

와 같은 형태로 union type과 동일하게 인라인으로 확장되어 트랜스파일된다

Tree-shaking에서도 동일하게 사용하지 않으면 번들에 포함되지 않기 때문에 일반 enum에 비해서 좋다

하지만

const enum을 사용하는 경우 일반 상수로 치환이 되기 때문에 실제 런타임에 실행되는 코드에서 코드 에러를 유발할 수 있고,
이를 방지하기 위하여 tsconfig compilerOptions에 isolatedModules 설정을 true로 설정하는 경우 const enum 또한 enum과 동일하게 즉시실행함수(IIFE)가 생성될 수 있기에 실행될때 100% 권장되지는 않는다고 한다.

또한 const enum은 babel 로 트랜스파일 될 수 없다.

( babel-plugin-const-enum를 사용하여 const enum → enum 또는 const enum → const object로 변경을 진행 시켜서 사용해야한다 )

 

 

 

++++

 

아니면

이렇게 as const도 가능~!

 

export const orderStatusKeys = {
  주문대기중: 'received',
  주문완료: 'accepted',
  제작중: 'making',
  픽업완료: 'completed',
  취소된주문: 'canceled',
} as const;

export type OrderStatusUnion =
  typeof orderStatusKeys[keyof typeof orderStatusKeys];

 

 

참고 

https://engineering.linecorp.com/ko/blog/typescript-enum-tree-shaking

 

TypeScript enum을 사용하지 않는 게 좋은 이유를 Tree-shaking 관점에서 소개합니다.

들어가며 안녕하세요. LINE Growth Technology UIT 팀의 Keishima(@pittanko_pta)입니다. 이번 글에서는 TypeScript의 enum을 사용하지 않는 편이 좋은 이유를 Tree-shaking 관점에서 소개하겠습니...

engineering.linecorp.com

https://velog.io/@sensecodevalue/Typescript-Enum-%EC%99%9C-%EC%93%B0%EC%A7%80-%EB%A7%90%EC%95%84%EC%95%BC%ED%95%98%EC%A3%A0

 

[Typescript] Enum 왜 쓰지 말아야하죠?

\*\* 급하신 분들은 맨아래 union Type을 사용하는 방법 및 결론을 바로 보세요~프로젝트를 진행 중 ts의 enum을 사용하지 않고 상수를 const object를 통해서 관리가 되고 있었습니다. 따라서, type | interfa

velog.io

https://www.kabuku.co.jp/developers/good-bye-typescript-enum

 

さようなら、TypeScript enum - 株式会社カブク

フロントエンドエンジニアの今村です。TypeScriptではenumを使わずunion型を使いましょう、という

www.kabuku.co.jp

https://velog.io/@hhhminme/%EB%84%A4-Enum-%EB%88%84%EA%B0%80-Typescript%EC%97%90%EC%84%9C-Enum%EC%9D%84-%EC%93%B0%EB%83%90

 

네 Enum! 누가 Typescript에서 Enum을 쓰냐!

Enum을 Tree-shaking관점으로 Typescirpt에서 더 효과적으로 사용하기 위해 Union Type으로 Migration 할 때 공부하였던 내용과 간단한 사용방법 및 검증을 다룬다.

velog.io