Skip to content

Commit 194198d

Browse files
committed
Fix: Post: enum-to-tempalte-literal
1 parent 5b02b2e commit 194198d

File tree

1 file changed

+39
-15
lines changed

1 file changed

+39
-15
lines changed

pages/posts/til/ts/enum-to-template-literal.mdx

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
# [TypeScript] `enum` -> `template literal` 갈아타기(+ `class-validator`에 적용하기)
1+
# [TypeScript] `enum` -> `literal` 타입 갈아타기(+`class-validator`, `template literal` 타입 활용)
22

33
### 3줄 요약
44

55
> - `enum`은 tree-shaking, memory-leak 문제가 있고, 여러 enum을 하나의 enum으로 합칠 수 없다
6-
> - `class-validator`에서 `IsEnum`을 쓰려면 단순 `template-literal` 타입은 안되고, 객체가 필요하다
7-
> - `template-literal``Readonly<Record<K, V>>` 유틸 타입을 활용해 문제를 해결했다
6+
> - `class-validator`에서 `IsEnum`을 쓰려면, 타입이 아닌 객체가 필요하다
7+
> - `literal``Readonly<Record<K, V>>` 유틸 타입을 활용해 문제를 해결했다
8+
9+
[👉 hashnode에서 보기](https://wiii.hashnode.dev/enum-to-template-literal)
810

911
---
1012

@@ -81,7 +83,7 @@ periodLogger('DAILY'); // error
8183

8284
<br />
8385

84-
타입 assertion으로는 가능하긴 하나..***아무 의미 없는 타입 선언***이 되어 버린다
86+
타입 assertion으로 에러를 안낼 수는 있는데..***아무 의미 없는 타입 선언***이 되어 버린다
8587

8688
![](https://images.velog.io/images/johnwi/post/669de5ad-34fb-4a23-b86e-a8cb8ea5326a/image.png)
8789

@@ -91,17 +93,17 @@ periodLogger('DAILY'); // error
9193

9294
## `class-validator``IsEnum`을 쓰려면 객체가 필요하다!
9395

94-
가장 속 편한건 단순히 `template-literal`'만' 쓰는 거다
96+
가장 속 편한건 단순히 `literal`'만' 쓰는 거다
9597

9698
토스 기술 블로그 [Template Literal Types로 타입 안전하게 코딩하기](https://toss.tech/article/template-literal-types)에서 소개하는 것처럼,
9799

98100
TypeScript에는 문자열을 가지고 다양한 타입을 만들어 낼 수 있는 재미있는(?) 기능이 있다
99101

100102
<br />
101103

102-
그러나 위에서 예시로 가져온 `Periods`는 단순히 함수 인자의 타입만 추론하는데 쓰는 것이 아니라,
104+
다만 위에서 예시로 가져온 `Periods`는 단순히 함수 인자의 타입만 추론하는데 쓰는 것이 아니라,
103105

104-
아래와 같이 **[`class-validator`](https://github.com/typestack/class-validator)를 활용해 API 요청 유효성 검사**를 하기 위해서다
106+
아래와 같이 **[`class-validator`](https://github.com/typestack/class-validator)를 활용해 API 요청 유효성 검사**에도 사용될 수 있어야했다
105107

106108
```typescript
107109
export class GetChartDto {
@@ -120,9 +122,11 @@ export class GetChartDto {
120122

121123
<br />
122124

123-
enum으로 union 만들 방법을 구글링(`'typescript enum union'`)하면 나에게 가장 먼저 뜨는 글은,
125+
위 라인 블로그에서 가장 추천하는 방법은 객체를 가지고 Union 타입을 만드는 것이다
126+
127+
enum으로 union 만들 방법을 구글링(`'typescript enum union'`)하면 나에게 가장 먼저 뜨는 글인
124128

125-
정규현님의 [enum type 대신 union type으로 변경하기](https://ajdkfl6445.gitbook.io/study/typescript/enum-type-union-type)이다
129+
정규현님의 [enum type 대신 union type으로 변경하기](https://ajdkfl6445.gitbook.io/study/typescript/enum-type-union-type)에서도 그 방식을 개선하여 사용한 경험을 보여주고 있다
126130

127131
여기서 핵심은 아래와 같다
128132

@@ -180,12 +184,34 @@ export const PeriodA: ReadonlyRecord<PeriodANames> = { /** */ }
180184

181185
<br />
182186

183-
### `template-literal` 타입; `PeriodNames`, `_RestPeriodNames`
187+
### `literal` 타입; `PeriodNames`, `_RestPeriodNames`
184188

185-
단순한 template-literal 타입이다
189+
단순한 문자열 literal 타입이다
186190

187191
Union이라는 의미에 맞게, ***관심사에 따라 분리된 타입들을 하나로 묶는 것이 쉽다***
188192

193+
`keyof typeof 객체`를 대신하기 위해 타입을 하나하나 더 써야한다는 것이 단점이기는 하지만,
194+
195+
아래 객체를 생성할 때 자동완성이 되기 때문에 크게 불편함을 느끼진 않을수 있다
196+
197+
오히려 하나의 타입에 너무 많은 속성이 있어서 타이핑 시간이 오래 걸릴 정도라면, 타입을 충분히 분리하지 못한 게 아닐지 검토해봐야 할 것 같다
198+
199+
또 토스 블로그에서 소개한 것처럼, **`template-literal` 타입들을 조합한 새로운 타입들을 선언하기 매우 편리해진다**
200+
201+
```typescript
202+
export type MarketNames = 'domestic' | 'overseas';
203+
export type CategoryNames = 'index' | 'stock';
204+
205+
export type DetailChartTypeNames = `${MarketNames}-${CategoryNames}`;
206+
export const DetailChartTypes: ReadonlyRecord<DetailChartTypeNames> = {
207+
'domestic-index': 'domestic-index',
208+
'domestic-stock': 'domestic-stock',
209+
'overseas-index': 'overseas-index',
210+
'overseas-stock': 'overseas-stock',
211+
};
212+
```
213+
214+
189215
<br />
190216

191217
### Readonly 객체를 `class-validator IsEnum`에 활용
@@ -199,10 +225,8 @@ export class GetChartDto {
199225
}
200226
```
201227

202-
`template-literal`을 활용하여 안전한(type-safe) `Readonly` 객체를 만들고, `class-validator`에서 활용한다
228+
`literal`을 활용하여 안전한(type-safe) `Readonly` 객체를 만들고, `class-validator`에서 활용한다
203229

204230
`class-validator`가 아니더라도, 기존 `enum` 사용하듯 `Periods.DAILY`와 같이 사용할 수도 있다
205231

206-
물론 이렇게 객체를 생성하면 **tree-shaking 문제는 해결되지 않는다**는 단점이 있다
207-
208-
다만 이 문제는 **`const enum`**을 쓰지 않는 한, 다른 방법들도 모두 동일할 것이다
232+
JS로 Transpile 되었을때, 단순 객체 리터럴이기 때문에 라인 블로그대로라면 tree-shaking도 가능하다

0 commit comments

Comments
 (0)