TypeScript 4.3 Template Literal Types로 타입 안전성 높이기

문제 상황

사내 분석 시스템에서 이벤트 이름이 user:login, order:created 같은 패턴을 따라야 하는데, 오타로 인한 버그가 자주 발생했다. 기존에는 string 타입으로만 처리하다 보니 컴파일 단계에서 잡을 수 없었다.

// 기존 방식 - 오타 감지 불가
type EventName = string;
const trackEvent = (name: EventName) => { /* ... */ };

trackEvent('user:logn'); // 오타지만 통과

Template Literal Types 적용

TypeScript 4.1부터 지원하는 Template Literal Types를 활용해 타입을 강제했다.

type EventCategory = 'user' | 'order' | 'product';
type EventAction = 'created' | 'updated' | 'deleted' | 'login' | 'logout';
type EventName = `${EventCategory}:${EventAction}`;

const trackEvent = (name: EventName) => {
  console.log(`Tracking: ${name}`);
};

trackEvent('user:login'); // OK
trackEvent('user:logn'); // 컴파일 에러
trackEvent('admin:login'); // 컴파일 에러

적용 결과

  1. IDE에서 자동완성이 정확하게 동작
  2. 잘못된 이벤트명 사용 시 즉시 에러 표시
  3. 리팩토링 시 안전성 확보

처음엔 Union이 너무 많아지면 성능 이슈가 있을까 걱정했는데, 실제로는 문제없었다. 다만 Category와 Action의 조합이 50개를 넘어가면 타입 체크가 느려질 수 있다는 점은 염두에 둬야 한다.

추가 활용

CSS 클래스명, API 엔드포인트 경로 등에도 같은 패턴을 적용 중이다.

type Route = `/api/${'users' | 'orders'}/${'list' | 'detail'}`;
// '/api/users/list', '/api/orders/detail' 등만 허용

Template Literal Types는 타입 안전성을 높이는 강력한 도구였다. 단순해 보이지만 실무에서 효과가 확실했다.

TypeScript 4.3 Template Literal Types로 타입 안전성 높이기