일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- react
- webpack
- swiper
- custom element
- 우아한테크코스 레벨3
- browserslist
- 데모데이
- HTML
- AX210
- 유한 상태 머신
- Grafana
- typescript
- 우테코
- RTL8852BE
- GitHub Pages
- docker-compose
- Shadow DOM
- 터치 스와이프
- 우아한테크코스
- CSS
- github Actions
- live share
- 무선랜카드 교체
- scroll-snap
- Docker
- web component
- Prometheus
- fastify
- javascript
- react-dom
- Today
- Total
IT일상
타입스크립트 템플릿 리터럴 타입 본문
리뉴얼 된 블로그로 보기: https://solo5star.dev/posts/31/
type Category = '한식' | '중식' | '일식' | '기타';
function printCategory(category: Category) {
// '한식', '중식', '일식', '기타' 중 하나
}
printCategory('한식'); // OK
printCategory('한...식'); // ERROR
위와 같이 문자열을 강제하는 String Literal Type을 사용하는 것은 자주 보셨을 겁니다.
타입스크립트의 기능 중 하나인 Template Literal Type을 사용하면 더 다양한 String Literal Type을 만들 수 있습니다.
기본적인 사용법
type HttpMethods = 'GET' | 'OPTION' | 'HEAD';
type HttpUrlPaths = '/animals' | '/fruits';
type HttpEndpoints = `${HttpMethods} ${HttpUrlPaths}`;
// 'GET /animals' | 'OPTION /animals' | 'HEAD /animals' | 'GET /fruits' | 'OPTION /fruits' | 'HEAD /fruits'
먼저, Back quote (`)를 사용하여 문자열을 나타냅니다. 그리고 ${} 를 사용하여 String Literal Type을 넣습니다. 템플릿에 삽입된 기존의 String Literal Type으로 새로운 String Literal Type이 만들어집니다.
예시: Union Type을 사용하여 만들기
type Events = 'click' | 'hover' | 'keyup' | 'keydown';
type EventHandlers = `on${Events}`;
// 'onclick' | 'onhover' | 'onkeyup' | 'onkeydown';
Events 라는 타입에서 on이라는 단어를 붙여 'onclick' | 'onhover' | 'onkeyup' | 'onkeydown' 라는 새로운 Union Type을 만들 수 있습니다.
예시: Primitive Type을 사용하여 만들기
type HttpEndpoints =
| `GET /animals/popular`
| `GET /animals/${number}`
| `GET /animals/search/${string}`;
number, string 타입을 넣을 수도 있습니다.
아쉽게도 number, string은 포괄적인 타입이므로 VSCode에서 자동완성으로 표시되지는 않습니다.
타입 자체는 의도한 대로 잘 작동하므로 참고하시면 될 것 같습니다.
참고로, boolean은 true | false로 잘 동작합니다.
예시: Conditional Type에서 사용하기
(Tistory의 TypeScript 코드블럭이 깨져서 VSCode 스크린샷으로 대체합니다.)
extends를 사용한 Conditional Type에서도 사용할 수 있습니다.
위의 예시에서는 인자로 주어진 selector 라는 문자열이 맨 끝에 ?가 붙어있는지 검사합니다. 이에 따라 리턴 타입이 결정됩니다.
예시: infer를 사용하여 String Literal Type 추출하기
type HttpEndpoints =
| `GET /animals/popular`
| `GET /animals/${number}`
| `GET /animals/search/${string}`
| `POST /animals`
| `POST /animals/${number}`
| `PUT /animals/${number}`;
type GetHttpMethods<T> = T extends `${infer U} ${string}` ? U : never;
type HttpMethods = GetHttpMethods<HttpEndpoints>;
// 'GET' | 'POST' | 'PUT'
기존의 String Literal Type에서 원하는 부분만 추출하여 사용할 수도 있습니다. Conditional Type과 함께 infer 키워드를 쓰면 해당 부분만 추출하는 타입을 만들 수 있습니다.
라이브러리
이러한 타입의 문법들을 응용하여 다양한 편리 기능들을 제공하는 라이브러리들이 많습니다.
* https://github.com/tani/jsonup: String Literal Type으로 된 JSON을 파싱한 타입으로 만들어 줍니다.
* https://github.com/g-plane/typed-query-selector: querySelector를 분석하여 적합한 반환 HTMLElement 타입을 만들어 줍니다.
빌트 인(Built-in) 타입 유틸리티
타입스크립트에 내장되어 있는 유틸리티 타입들입니다. 간단한 것들이기 때문에 설명 없이 입출력만 첨부하였습니다.
Uppercase<StringType>
Lowercase<StringType>
Capitalize<StringType>
Uncapitalize<StringType>
맺음말
기존에는 String Literal Type을 일일이 하드코딩하여 타입을 정의해주어야 했습니다. 하지만 Template Literal Type을 사용하면 더 강력한 타입들을 만들 수 있을 겁니다! 특히 Conditional Type과 잘 연계해서 쓴다면 정말 멋진 타입을 만들어 나갈 수 있지 않을까 싶습니다.
참고자료
* https://toss.tech/article/template-literal-types
* https://www.typescriptlang.org/docs/handbook/2/template-literal-types.html
'프론트엔드' 카테고리의 다른 글
CSS로 별점 기능 만들기 (2) | 2023.03.27 |
---|---|
타입스크립트 Discriminated Unions (0) | 2023.03.27 |
[Web Component] 커스텀 폼 컨트롤, form associated 컴포넌트 만들기 (2) | 2023.03.07 |
[Web Component] Custom Element에서 slot 사용하기 (2) | 2023.03.06 |
[Web Component] 컴포넌트 내부 요소를 격리하기. HTML Custom Elements + Shadow DOM (0) | 2023.02.27 |