Typescript enum 대신 as const 를 사용합시다

shleecloud·2023년 10월 26일
0
post-thumbnail

들어가며

전 회사에서 enum을 많이 활용했다. 이전부터 사용하던 코드 양식이면서 사용법도 편하고 코드도 깔끔해지고 문제 없어보였다. 이번 글도 큰 문제가 있어서 쓰는 글은 아니다. 작은 문제인데 쌓이면 무시하기 애매한 enum에 대한 내용이다.

Treeshacking이 되지 않는 enum

enum의 문제는 Treeshacking이 안된다는 점이다. 호출하지 않는 enum도 변환해서 불러온다. 번들러에서 TS에서 생성한 코드가 정말 실행되지 않는지 확신할 수가 없어서 제거하지 않는다.

enum StatusEnum {
  CASH = 'CASH',
  CARD = 'CARD',
  POINT = 'POINT',
}
// const a1 = StatusEnum.CASH 호출하지 않아도 불러온다. 

// ---
"use strict";
var StatusEnum;
(function (StatusEnum) {
    StatusEnum["CASH"] = "CASH";
    StatusEnum["CARD"] = "CARD";
    StatusEnum["POINT"] = "POINT";
})(StatusEnum || (StatusEnum = {}));

인라인화의 단점 const enum

enum과 다르게 사용하지 않는 값이 변환되지 않는다. 하지만 여전히 단점이 있다. 인라인화 된다는 점이다.

  • 변형된 값의 끝을 보면 주석이 달려있다. 이 부분까지 합해서 번들링이 이루어진다. 이 주석이 한자나 한글처럼 길게 변환될 경우 이 부분까지 포함되어 번들링된다.
  • 인라인화 단점 두 번째로 변수로 호출하지 않고 문자열로 호출한다. 참조 호출하지 않고 값을 따로 만들면서 비효율이 생긴다.
  • 세 번째로 원시 자료형만 허용된다.
const enum StatusConstEnum {
  CASH = 'CASH',
  CARD = 'CARD',
  POINT = 'POINT',
  KOREAN = '한글이 길어지면 변환되는 주석도 점점 길어지고 번들 사이즈도 길어집니다',
  // ARR = [[[{}]]]
}

const b1 = StatusConstEnum.CASH
const b2 = StatusConstEnum.KOREAN

// ---
"use strict";
const b1 = "CASH" /* StatusConstEnum.CASH */;
const b2 = "\uD55C\uAE00\uC774 \uAE38\uC5B4\uC9C0\uBA74 \uBCC0\uD658\uB418\uB294 \uC8FC\uC11D\uB3C4 \uC810\uC810 \uAE38\uC5B4\uC9C0\uACE0 \uBC88\uB4E4 \uC0AC\uC774\uC988\uB3C4 \uAE38\uC5B4\uC9D1\uB2C8\uB2E4" /* StatusConstEnum.KOREAN */;

대세는 as const ⭐

TS를 가장 TS 스럽게, JS의 슈퍼셋으로 사용하는 방법이다.
TS 코드를 Treeshacking을 사용할 수 있게 담백하게 만들어준다.

const StatusAsConst = {
  CASH: 'CASH',
  CARD: 'CARD',
  POINT: 'POINT',
  KOREAN: '한글이 길어지면 변환되는 주석도 점점 길어지고 번들 사이즈도 길어집니다',
  ARR: [[[{}]]]
} as const // <- const 어설션이 객체를 상수처럼 만들어준다

const c1 = StatusAsConst.CASH
const c2 = StatusAsConst.KOREAN

type StatusAsConst = typeof StatusAsConst[keyof typeof StatusAsConst]
// type StatusAsConst = "CASH" | "CARD" | "POINT" | "한글이 길어지면 변환되는 주석도 점점 길어지고 번들 사이즈도 길어집니다" | readonly [readonly [readonly [{}]]]
const cf = (e: StatusAsConst): StatusAsConst => e

// ---
"use strict";
const StatusAsConst = {
    CASH: 'CASH',
    CARD: 'CARD',
    POINT: 'POINT',
    KOREAN: '한글이 길어지면 변환되는 주석도 점점 길어지고 번들 사이즈도 길어집니다',
    ARR: [[[{}]]]
};
const c1 = StatusAsConst.CASH;
const c2 = StatusAsConst.KOREAN; // 문자열이 아닌 참조로 호출한다
const cf = (e) => e;
// 마우스오버 해보면 readonly가 붙는다. 참조자료형 내부에도 붙는다. 
const StatusAsConst: {
    readonly CASH: "CASH";
    readonly CARD: "CARD";
    readonly POINT: "POINT";
    readonly KOREAN: "한글이 길어지면 변환되는 주석도 점점 길어지고 번들 사이즈도 길어집니다";
    readonly ARR: readonly [readonly [readonly [{}]]];
}

참조 URL

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

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

https://xpectation.tistory.com/218

profile
블로그 옮겼습니다. https://shlee.cloud

0개의 댓글