노트

템플릿 리터럴 타입

Template Literal Types

프런트엔드#ts · 연결된 개념 5개

쉽게 말하면

템플릿 리터럴 타입은 'btn-' 같은 문자열 틀에 후보 목록을 끼워 가능한 조합을 모두 만들어 주는 타입이에요. 음료 크기 둘과 맛 둘을 고르면 주문 가능한 네 가지가 정해지듯, 팀의 문자열 규칙을 타입으로 강제하죠.

비유가 깨지는 곳 후보 수를 곱한 만큼 조합이 늘어나요. 크기와 맛이 몇 개 안 될 땐 괜찮지만 유니언이 커지면 조합이 폭발해서 컴파일이 느려지니 크기를 의식해야 해요.

템플릿 리터럴 타입(Template Literal Types)은 문자열 리터럴 타입을 템플릿 문자열 문법으로 조합해 새 문자열 유니언을 만드는 기능이다. 유니언을 넣으면 가능한 모든 조합이 나온다.

type Size = 'sm' | 'md'
type Variant = 'primary' | 'secondary'
type ClassName = `btn-${Variant}-${Size}`
// 'btn-primary-sm' | 'btn-primary-md' | 'btn-secondary-sm' | 'btn-secondary-md'
 
type Field = 'email' | 'password'
type Handler = `on${Capitalize<Field>}Change`   // 'onEmailChange' | 'onPasswordChange'
type LocaleKey = `common.${string}`              // 접두사 규칙만 강제
  • 이벤트 이름, CSS(Cascading Style Sheets) 클래스 규칙, i18n(Internationalization) 키, API(Application Programming Interface) 경로 패턴처럼 팀의 문자열 규칙을 타입으로 강제할 때 쓴다
  • Uppercase·Lowercase·Capitalize·Uncapitalize 같은 내장 문자열 변환 타입과 함께 쓴다
  • 매핑된 타입의 as 절과 합치면 { getName: …; getAge: … }처럼 키 이름을 바꾼 타입도 만들 수 있다
  • 조합 수가 폭발하면 컴파일이 느려진다. 유니언 크기를 의식한다

문자열 규칙 대신 아예 값을 분리하는 방법은 enum과 as const 객체, 클래스 이름 조합을 런타임에서 다루는 도구는 cn 유틸리티(clsx·tailwind-merge·cva).

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • 유니언·인터섹션·리터럴 타입

    유니언 타입(Union Type, A | B)은 "A이거나 B인 값"이고, 인터섹션 타입(Intersection Type, A & B)은 "A이면서 B인 값"이다. 리터럴 타입(Literal Type)은 'left'나 3처럼 특정 값 하나만 허용하는 타입이다.

  • 유틸리티 타입

    유틸리티 타입(Utility Types)은 기존 타입에서 새 타입을 만들어 주는 TypeScript 내장 제네릭 타입이다. 같은 모양을 손으로 다시 선언하지 않게 해 준다.

  • 기본형 집착

    전화번호·금액·우선순위 같은 도메인 개념을 끝까지 문자열이나 숫자로만 다루는 냄새. 같은 검증과 포맷 코드가 여기저기 반복되고, 문자열로 모든 걸 표현하는 "stringly typed" 코드가 된다.

  • Tailwind CSS

    flex, px-4, text-sm처럼 속성 하나를 담은 유틸리티 클래스(Utility Class)를 마크업에 조합해 스타일을 입히는 CSS 프레임워크. 빌드할 때 소스를 훑어 실제로 쓰인 클래스의 CSS만 만들어 내는 빌드 도구이고, 런타임에 돌아가는 JS(JavaScript)는 없다.

  • type과 interface

    type(타입 별칭, Type Alias)과 interface는 둘 다 타입에 이름을 붙이는 방법이다. 객체 모양을 정의할 때는 대부분 바꿔 써도 되지만, 확장 방식과 표현 범위가 다르다.

보기 옵션