typescript에서 지원하는 타입중 Enum이라는 타입이 있습니다. 이는 다른 언어에서 보통 상수를 만들 때 사용합니다. (상시 그대로인 수를 상수로 알고있었습니다.) 하지만 자바스크립트에서는 const
라는 키워드를 통해서 상수를 만듭니다. typescript에서는 왜 const
라는 키워드를 내버려두고 Enum 타입을 추가하였을까 궁금해서 찾아보게 되었습니다.
Enum (Enumerated type)은 열거형 타입으로 자바스크립트에는 존재하지 않지만 다른 언어나 타입스크립트에는 존재하는 타입입니다, Typescript에서는 숫자기반 뿐만 아니라 문자열 기반의 열거형까지도 지원합니다.
Enum의 대표적인 예로서 Boolean 타입을 생각해볼 수 있습니다.
enum booleanType {
False = 0,
True = 1
}
위 코드를 컴파일을 할경우 다음과 같이 바뀝니다.
"use strict";
var booleanType;
(function (booleanType) {
booleanType[booleanType["False"] = 0] = "False";
booleanType[booleanType["True"] = 1] = "True";
})(booleanType || (booleanType = {}));
위 함수는 즉시실행함수로서 다음과 같이 변경이 됩니다.
var booleanType = {
"0": "False",
"1": "True",
"False": 0,
"True": 1
}
그러면 다음과 같이 접근할 수 있는 것입니다.
console.log(booleanType[0]); // False
console.log(booleanType[1]); // True
console.log(booleanType["True"]); // 1
console.log(booleanType["False"]); // 0
이처럼 Enum 타입을 사용하면 양방향으로 접근할 수 있는 객체가 만들어진다고 보시면 됩니다.
개발자가 보기 쉽게 작성하여 코드 작성시 쉽게 접근할 수 있게 작성할 수 있습니다. 예를 들어 booleanType[0]
과 같이 키와 밸류로 구성이 되어있기 때문에 해당 값을 쉽게 추론할 수 있습니다.
정해져있는 키와 밸류 값 이외에는 접근을 할 수 없으므로 오류로 부터 거리가 있습니다.
Enum을 통해 자동완성 기능이 가능하므로 생산성을 증가시킬 수 있습니다.
컴파일시 코드의 양이 증가합니다. boolean : "0"
이라는 값만 있어도 되는데 0 : boolean
이라는 값 도 생기기 때문에 기존보다 코드의 양이 많아지게 됩니다.
Tree-shaking이 되지 않습니다. 저는 이게 가장 큰 단점이라고 생각합니다. 나무를 흔들어서 죽은 잎사귀나 나뭇가지를 떨어트리는 행동에서 Tree-shaking이라는 말이 유래하였습니다. 즉 가비지 콜렉터와 같이 버려진 코드들이 사라지지 않습니다. 따라서 Enum을 선언만 해두었더라도 해당 코드들은 살아서 단점의 1번과 같이 많은 양의 코드들이 노출되어있게 됩니다.
Enum을 사용하게 될 경우 정해진 키와 값을 통해서 고정된 상수를 가지게 됩니다. 따라서 const
키워드를 사용하여 상수를 사용하면 안될까요?
const를 사용할 경우 다음과 같은 일이 벌어질 수 있습니다.
const userInfo = {
name: 'marin',
age: 20,
height: 200
}
userInfo.name = 'brian';
const
를 통해서 선언을 하였지만 brian
으로 변경이 되는 것을 볼 수 있다. 그럼 많은 코드를 쓰면서까지 Enum을 사용해야할까?
이럴때 나온 문법이 바로 as const
이다.
const userInfo = {
name: 'marin',
age: 20,
height: 200
} as const
userInfo.name = 'brian';
다음과 같이 객체를 만들고 나서 마지막에 as const
를 붙여주었다. 그러자 다음과 같은 에러가 발생하였다.
as const
를 붙였기 때문에 해당 name이 readonly 키값이 되어버린 것이다. 이 as const
는 사실 객체에 직접 붙이지 않고 value에 붙일수도 있다.
위 사진을 통해 as const
가 붙여져있는 name만 에러가 발생하는 것을 확인할 수 있다.
그럼 객체를 고정하기 위해서 사용하는 건가? 라고 볼 수도 있다. 이뿐만이 아니라 let
키워드와 같이 변경이 가능한 변수에도 as const를 붙여줌으로서 read only 값이 될 수 있다.
type name = string;
let user: name = "marin";
user = "jihyeong";
console.log(user); // jihyeong
---
type name = string;
let user: name = "marin" as const;
user = "jihyeong"; // Error
console.log(user)
처음 Enum 처럼 양방향 바인딩이 가능하지는 않지만 as const
를 통해서 상수가 아닌 값을 상수로 만들 수 있다.
Enum은 양방향 바인딩이 된다. 코드의 길이가 길어진다. true/false와 같이 잘 사용할 수 있으면 쓰자. 하지만 tree-shaking이 안되기 때문에 추천하지는 않는다.
as const는 타입 추론을 통해 타입을 나타내고 상수로 만들어주기까지 한다. 또 Object와 같이 값이 변경이 되는 변수들도 readonly 속성을 부여함으로써 값을 고정할 수 있다.