My Boundary As Much As I Experienced

as const와 enum 중에 무엇을 쓸까 본문

FrontEnd/TypeScript

as const와 enum 중에 무엇을 쓸까

Bumang 2024. 5. 9. 23:22

공부하게 된 계기

타입스크립트에는 constant 관리에 2가지 선택지가 있다. as const와 enum이다.

나는 보통 as const를 쓰는 편이었는데 (그냥.. const가 친숙해서 썼었다. enum은 넘 생소해..)

회사에선 enum을 쓰더라. 왜 enum을 쓰는지 궁금해서 사수님께 물어보기 전에

채찍피티와 오픈채팅방에 as const vs enum에 대해 물어보고 기록한 내용이다.

 

대강 정리하자면...

 

보통 자바스크립트에 친숙한 개발자는 enum보단 as const를 선호하는 경향이 크나, 개발팀 리더가 자바 경력이 긴 사람이면 enum으로 통일하는 경우도 있다고 한다. 그리고 enum은 참조되지 않아도 트리쉐이킹의 대상이 되지 않기도 하며, 컴파일 시 즉시실행함수 IIFE로 변환되어 흔적이 남는다고 한다. 고작 몇 kb의 추가 용량일테지만 어쨌든 as const 보단 비용이 비싸니까 안 쓰는 이유로 꼽기도 한다고 한다.

 

그러나 중론은 '성능차 의미없다. 팀에서 선호하는걸로 맞춰라.'인거 같다.

음.. 내일 사수님께 우리팀이 enum을 택한 이유가 뭔지 물어봐야겠다.

 

하여튼 스터디 했던 내용들을 아래 적어보았다.

 

기본 enum 사용법

enum은 타입스크립트에서 상수들의 집합을 정의하는 방법이다.

enum Color {
    Red,
    Green,
    Blue
}

let color: Color = Color.Red;

console.log(color); // 출력: 0

 

위의 예제에서는 Color라는 enum을 정의하고 Red, Green, Blue라는 값을 가진다.

기본적으로 enum의 값은 0부터 시작하여 1씩 증가한다.

따라서 Color.Red는 0, Color.Green은 1, Color.Blue는 2가 된다.

 

수동으로 값 지정

enum의 각 값에 수동으로 숫자를 할당할 수도 있다.

enum Color {
    Red = 1,
    Green = 2,
    Blue = 4
}

let color: Color = Color.Green;

console.log(color); // 출력: 2

 

문자열 enum

숫자 대신 문자열 값을 가질 수도 있다.

enum Color {
    Red = "RED",
    Green = "GREEN",
    Blue = "BLUE"
}

let color: Color = Color.Blue;

console.log(color); // 출력: BLUE

 

역방향 매핑

숫자 enum에서는 값을 통해 원래의 이름을 찾을 수 있다.

단, 문자열 enum에서는 역방향 매핑이 작동하지 않는다.

enum Color {
    Red,
    Green,
    Blue
}

let colorName: string = Color[0];

console.log(colorName); // 출력: Red

 

enum 활용 예제

다음은 enum을 사용하여 switch 문과 결합한 예제이다.

enum Color {
    Red,
    Green,
    Blue
}

function getColorName(color: Color): string {
    switch (color) {
        case Color.Red:
            return "Red";
        case Color.Green:
            return "Green";
        case Color.Blue:
            return "Blue";
        default:
            return "Unknown color";
    }
}

let color: Color = Color.Green;

console.log(getColorName(color)); // 출력: Green

 

이와 같이 TypeScript에서 enum을 사용하면 상수들을 더욱 직관적으로 관리할 수 있으며,

코드의 가독성을 크게 향상시킬 수 있다..

라고 한다.

 

enum의 단점 - Tree shaking이 안됨

이넘을 선호하지 않는 사람들이 많이 말하는 것 중에 하나가

enum은 타입임에도 불구하고 컴파일 될 때 사라지지 않고 메모리를 점유한다는 점이다.

 

또한 보통 웹개발에서 어떤 코드가 export 되거나 다른 곳에서 참조되지 않을 시에는

webpack같은 컴파일러가 트리쉐이킹(tree shaking)을 하여 코드를 없애주는데,

enum은 즉시실행함수(IIFE)로 변환되어.. 즉시 실행된다. (당연하게도.)

그래서 참조되지 않아도 트리쉐이킹의 대상이 되지 않아 메모리에 남게 된다.

 

이런 연유로 enum을 싫어하는 성능주의자들이 존재한다고 한다.

(그러나 고작 몇 kb일 뿐이니 성능 때문에 enum을 쓰지 않는다는 것은 과하다는 사람들도 많다.)

// 이것이
enum Color {
    Red,
    Green,
    Blue
}

// 아래처럼 된다.

"use strict";
var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Green"] = 1] = "Green";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));

 

대안으로의 as const?

as const는 as와 const로 이루어져 있다... 는 그냥 해본 소리고

자바스크립트에 친숙한 사용자라면 직관적으로 이해할 수 있다.

'아아 객체인데 수정 불가능한 상태가 되는구나' 싶다.

 

그러나 key만 불러온다거나 value만 불러온다거나 하려면 아래처럼 조금 번거롭게 코드를 쳐야한다.

keyof와 typeof의 조합으로 쳐야한다.

(그래서 keyof와 typeof의 한바탕 쇼를 벌이고 싶지 않은 사람들이 깔끔한 문법의 enum을 쓰는거 같기도 하다.)

const Color = {
    Red: 'Red!',
    Green: 'Green!',
    Blue: 'Blue!'
} as const;

// typeof의 활용법
type ColorType = typeof Color;
// {
//     readonly red: "red";
//     readonly green: "green";
//     readonly blue: "blue";
// }

// Key만 불러오기
type ColorKey = keyof typeof Color;
// 'Red' | 'Green' | 'Blue'

// Value만 불러오기
type ColorValue = typeof Color[keyof typeof Color];
// 'Red!' | 'Green!' | 'Blue!'

 

하여튼 enum과 as const 두가지 선택지 모두 장단이 있고, 개발팀의 성향에 따라 달리 쓰면 될 것이다.

enum과 as const의 차이에 대해 잘 비교해보면서 keyof와 typeof도 직접 써보면서 숙련도를 좀 올린 것 같아 뜻깊었다.

 

 

참고자료

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