3 min read

TypeScript satisfies 연산자 완벽 가이드

TypeScript 4.9에서 도입된 satisfies 연산자의 사용법과 실무 활용 패턴을 알아봅니다.

TypeScriptJavaScript

TypeScript 4.9에서 도입된 satisfies 연산자는 타입 안전성을 유지하면서도 더 정확한 타입 추론을 가능하게 해주는 강력한 기능입니다.

문제 상황: 타입 단언의 한계

기존에는 객체의 타입을 명시할 때 두 가지 방법이 있었습니다:

// 방법 1: 타입 어노테이션
const colors: Record<string, string> = {
  red: "#ff0000",
  green: "#00ff00",
  blue: "#0000ff",
};
 
// 문제: colors.red의 타입이 string이 아닌 string | undefined
colors.red.toUpperCase(); // 에러 가능성
// 방법 2: as const
const colors = {
  red: "#ff0000",
  green: "#00ff00", 
  blue: "#0000ff",
} as const;
 
// 문제: 타입 검증이 없음 - 오타가 있어도 모름

satisfies의 등장

satisfies는 이 두 가지 문제를 동시에 해결합니다:

type Colors = Record<string, string>;
 
const colors = {
  red: "#ff0000",
  green: "#00ff00",
  blue: "#0000ff",
} satisfies Colors;
 
// ✅ 타입 검증 완료
// ✅ colors.red는 정확히 "#ff0000" 타입
colors.red.toUpperCase(); // 안전하게 호출 가능

실무 활용 패턴

1. 설정 객체 타입 검증

interface Config {
  apiUrl: string;
  timeout: number;
  features: {
    darkMode: boolean;
    notifications: boolean;
  };
}
 
const config = {
  apiUrl: "https://api.example.com",
  timeout: 5000,
  features: {
    darkMode: true,
    notifications: false,
  },
} satisfies Config;
 
// config.apiUrl은 string이 아닌 
// "https://api.example.com" 리터럴 타입

2. 라우트 정의

type Route = {
  path: string;
  component: string;
  auth?: boolean;
};
 
const routes = {
  home: { path: "/", component: "Home" },
  dashboard: { path: "/dashboard", component: "Dashboard", auth: true },
  profile: { path: "/profile/:id", component: "Profile", auth: true },
} satisfies Record<string, Route>;
 
// routes.home.path는 "/" 타입 (string이 아님)

satisfies vs 타입 단언(as)

| 특성 | satisfies | as | |------|-----------|-----| | 타입 검증 | ✅ 컴파일 타임에 검증 | ❌ 검증 없음 | | 타입 추론 | ✅ 좁은 타입 유지 | ❌ 단언한 타입으로 확장 | | 안전성 | ✅ 높음 | ⚠️ 낮음 |

결론

satisfies 연산자는 TypeScript의 타입 시스템을 한 단계 더 발전시킨 기능입니다. 특히 설정 객체, 라우트 정의, 상수 맵 등을 다룰 때 적극적으로 활용해보세요.