---
id: typescript-template-literal-types
title: TypeScript Template Literal Types
category: Coding
status: draft
source_trust_level: B
verification_status: conceptual
created_at: 2026-05-09
updated_at: 2026-05-09
tags: [typescript, types, template-literal, vibe-coding]
tech_stack: { language: "TypeScript 4.1+", applicable_to: ["Web", "Backend"] }
applied_in: []
aliases: [string template type, type-level string]
---

# Template Literal Types

> 타입 레벨에서 문자열 조합. CSS 단위, 라우트 path, event 이름 등 **"이 string 은 정확히 이런 형식이어야 한다"** 를 컴파일러가 검증.

## 📖 핵심 개념
백틱 + ${} 가 타입에서도 동작. union 과 결합하면 자동으로 cartesian product 생성.

## 💻 코드 패턴

### 1. 단위 검증
```ts
type CSSValue = `${number}px` | `${number}rem` | `${number}%`;

const ok: CSSValue = '12px';   // ✅
const bad: CSSValue = '12';    // ❌ 단위 없음
```

### 2. 이벤트 이름
```ts
type Domain = 'user' | 'order' | 'payment';
type Action = 'created' | 'updated' | 'deleted';
type Event = `${Domain}.${Action}`;
// 'user.created' | 'user.updated' | ... 9개 자동 생성

function on<E extends Event>(event: E, handler: (e: E) => void) { ... }
on('user.created', e => ...); // ✅
on('user.exploded', e => ...); // ❌
```

### 3. Route 파라미터 추출
```ts
type ExtractParams<T extends string> =
  T extends `${string}:${infer Param}/${infer Rest}` ? Param | ExtractParams<`/${Rest}`> :
  T extends `${string}:${infer Param}` ? Param : never;

type P = ExtractParams<'/users/:userId/posts/:postId'>;
// 'userId' | 'postId'

function buildRoute<R extends string>(template: R, params: Record<ExtractParams<R>, string>): string { ... }
buildRoute('/users/:userId', { userId: '1' }); // ✅
buildRoute('/users/:userId', { wrongKey: '1' }); // ❌
```

### 4. SQL-ish builder
```ts
type Op = 'eq' | 'gt' | 'lt' | 'in';
type Filter = `${string}__${Op}`;

function where(filter: Filter, value: any) { ... }
where('age__gt', 18); // ✅
where('age', 18); // ❌
```

## 🤔 의사결정 기준
| 사용처 | 적합 |
|---|---|
| 정해진 형식의 식별자 (event, key) | ✅ |
| 라우트 / URL 파라미터 | ✅ |
| CSS 단위 / 색상 형식 | ✅ |
| 자유 텍스트 | ❌ — 그냥 string |
| 매우 큰 union (1000+) | ❌ — 컴파일 느려짐 |

## ❌ 안티패턴
- **거대 union 생성**: `${A}-${B}` 에서 A,B 각 100 element → 1만 union. 컴파일러 폭사.
- **runtime 검증 없이 의존**: API 응답 string 을 `as Event` 캐스팅 — 형식 위반 가능. 검증 + brand 결합.
- **template literal 로 정규식 흉내**: 부분적으로만 가능. 진짜 정규식 검증은 런타임.

## 🤖 LLM 활용 힌트
- "이 string parameter 가 정해진 형식이면 template literal type 으로" 명시.
- 라우트 빌더 / 이벤트 emitter 에 자주 적용.

## 🔗 관련 문서
- [[TypeScript_Branded_Types]]
- [[TypeScript_Const_Assertions]]
