[TS] enum, const enum, const assertion

장동균·2022년 2월 15일
0

enum(열거형)

열거형은 키에 값을 할당하는, 순서가 없는 자료구조이다. 문자열에서 문자열로 매핑되거나 문자열에서 숫자로 매핑하는 열거형 이렇게 두 가지가 존재한다. 값을 명시하지 않는다면 타입스크립트는 자동으로 열거형의 멤버에 적절한 숫자(이전 값 + 1, default는 0)를 추론해 할당한다.

// 내가 작성한 코드
enum Language {
	English,
  	Spanish,
  	Russian
}

// 타입스크립트가 값을 추론한 결과
enum Language {
  	English = 0,
  	Spanish = 1,
  	Russian = 2
}
// 내가 작성한 코드
enum Language {
	English = 0,
  	Spanish = 500,
  	Russian
}

// 타입스크립트가 값을 추론한 결과
enum Language {
	English = 0,
  	Spanish = 500,
  	Russian = 501
}

편리해보이는 enum은 크게 두 가지 문제점을 가진다.

  1. 타입스크립트의 enum은 키를 통해 값에 접근할 수도, 값을 통해 키에 접근할 수도 있다. 이는 불안정한 결과를 초래한다.

    enum Color {
        Red = '#c10000',
        Blue = '#007ac1',
        Pink = 0xc10050,  // 16진수 리터럴
        White = 255  // 10진수 리터럴
    }
    
    console.log(Color.Red)  // '#c10000'
    console.log(Color.Blue)  // '#007ac1'
    console.log(Color[255])  // 'White'
    console.log(Color[0])  // undefined
    console.log(Color[1])  // undefined
    console.log(Color[2])  // undefined

    타입스크립트는 존재하지 않는 값인 Color[0], Color[1], Color[2]에 대한 접근을 막지 않는다.

  2. 불필요한 자바스크립트 코드를 발생시켜 tree-shaking을 방해한다.

    enum은 타입스크립트가 자체적으로 구현하는 기능이다. 자바스크립트에서는 사용이 불가능하기 때문에 이를 자바스크립트에서도 사용하기 위해 불필요한 코드들이 작성된다.


+추가
https://github.com/microsoft/TypeScript/pull/15486
string 값만을 사용한다면 enum에서의 reverse mapping은 발생하지 않는다.

https://velog.io/@vraimentres/typescript-enum
enum을 사용하지 않는 것이 큰 개선은 아니다.


const enum

이러한 enum의 단점을 보완하는 기능이 const enum이다.
const enumenum에서는 가능했던 역방향 찾기(값을 통해 키를 찾는 기능)를 지원하지 않는다. const enum의 멤버는 문자열 리터럴로만 접근이 가능하다.

const enum Language {
	English,
  	Spanish,
  	Russian
}

console.log(Language.English) // 0
console.log(Language.Spanish) // 1
console.log(Language[0]) // Error

또한 const enum은 기본적으로 아무 자바스크립트 코드도 생성하지 않는다. 그 대신 필요한 곳에 열거형 멤버의 값을 채워 넣는다.

하지만, const enum 또한 분명한 단점들이 존재한다.

  1. 값을 채워넣는 const enum의 방식이 문제를 일으킬 수 있다. const enum의 값이 갱신되면 버전에 따라 다른 값을 갖게 되는 문제가 발생한다. 때문에 npm으로 배포하거나 라이브러리로 제공할 프로그램에서는 const enum을 사용해서는 안된다.

  2. CRA bolerplate나 Next를 사용한다면 const Enum 사용했을 때 에러가 난다고 한다.

  3. tsconfig에서 isolatedModules 옵션을 true로 설정하게 되면 enum과 크게 차이가 없어진다.


const assertion

enumconst enum이 가진 문제들을 해결할 수 있는 기능이 const assertion이다. 뒤에 as const가 붙는다는 점을 빼면 자바스크립트에서 객체를 만드는 방식과 동일하다.

다만 const assertion을 사용할 때는 값을 생략할 수 없다.


결론

마치 const assertion이 최고인 것처럼 작성해놓았지만 팀의 선택에 맞추어 사용하면 될 것 같다.


참고문헌

https://engineering.linecorp.com/ko/blog/typescript-enum-tree-shaking/
https://www.typescriptlang.org/ko/docs/handbook/enums.html#objects-vs-enums
https://darrengwon.tistory.com/1310
타입스크립트 프로그래밍(프로그래밍 인사이트, 보리스 체르니 지음)

profile
프론트 개발자가 되고 싶어요

0개의 댓글