본문 바로가기
카테고리 없음

TypeScript satisfies 연산자 사용법과 예제

by logsome 2025. 2. 23.

1. TypeScript satisfies 연산자란?

TypeScript 4.9에서 도입된 satisfie 연산자는 객체가 특정 타입을 만족하는지 검증하면서도, 값의 원래 타입을 유지할 수 있도록 도와주는 연산자입니다. 기존에는 as를 사용하여 타입을 변환했지만, 이 방법은 타입을 너무 넓게 만들거나 불필요한 타입 오류를 발생시키는 문제가 있었습니다. satisfies를 사용하면 타입 안정성을 높이면서도 더 정밀한 타입 추론을 할 수 있습니다. 


2. satisfies 연산자로 해결할 수 있는 문제

2.1 타입을 만족하면서도 세밀한 타입 추론 유지

기존에는 객체의 타입을 만족시키기 위해 as를 사용했지만, 이 방법은 값의 타입을 넓게 만들어 불필요한 타입 오류를 발생시키곤 했습니다.

as를 사용할 경우 타입이 넓어짐

type Status = "success" | "error" | "loading";

const response = {
  status: "success",
  data: { message: "Operation completed" },
} as { status: Status; data: { message: string } };

function handleStatus(status: "success" | "error") {
  if (status === "success") {
    console.log("Success!");
  } else {
    console.log("Error!");
  }
}

// ❌ TypeScript가 "loading"도 가능하다고 판단하여 타입 에러 발생!
handleStatus(response.status); // Argument of type 'Status' is not assignable to parameter of type '"success" | "error"'.
  Type '"loading"' is not assignable to type '"success" | "error"'.

satisfies를 사용하면 타입이 좁게 유지됨

const response = {
  status: "success",
  data: { message: "Operation completed" },
} satisfies { status: Status; data: { message: string } };

handleStatus(response.status); // ✅ 정확한 타입 추론이 이루어져 타입 에러 없음

✔️ satisfies를 사용하면 response.status"success"로 유지되므로, handleStatus 함수에서 "loading"을 받을 가능성이 사라집니다.


2.2 잘못된 키 추가 방지 (객체의 키를 제한하는 경우)

as를 사용하면 잘못된 키 추가 시 오류 감지 불가능

type ButtonVariant = "primary" | "secondary" | "danger";

const buttonStyles = {
  primary: { color: "blue", text: "Click me" },
  secondary: { color: "gray", text: "Cancel" },
  danger: { color: "red", text: "Delete" },
  warning: { color: "yellow", text: "Caution" }, // ❌ 타입 오류 감지되지 않음
} as Record<ButtonVariant, { color: string; text: string }>;

satisfies를 사용하여 잘못된 키 감지 가능

type ButtonVariant = "primary" | "secondary" | "danger";

const buttonStyles = {
  primary: { color: "blue", text: "Click me" },
  secondary: { color: "gray", text: "Cancel" },
  danger: { color: "red", text: "Delete" },
  // ✅ satisfies를 사용하여 잘못된 키 사용 감지
  warning: { color: "yellow", text: "Caution" }, // Object literal may only specify known properties, and 'warning' does not exist in type 'Record<ButtonVariant, { color: string; text: string; }>'.
} satisfies Record<ButtonVariant, { color: string; text: string }>;

✔️ satisfies를 사용하면 잘못된 키(예: "warning")가 추가될 경우 즉시 타입 에러가 발생합니다.


3. satisfies를 활용해야 하는 경우 비교

구분 as satisfies 비고
타입 단언 (Type Assertion) 타입을 강제로 지정하며, 실제 타입 검사를 수행하지 않음 타입을 만족하는지 체크하며, 원래 타입을 유지 타입을 만족하는지 확인하면서도 원래 타입을 유지해야 할 때
넓은 타입 → 좁은 타입 변환 가능하나, 타입 검증 없이 단언 타입을 만족하는지 체크하여 안전한 변환 가능 특정 구조를 만족하는지 확인하면서 변환해야 할 때
객체 리터럴 타입 체크 타입 검사를 수행하지 않음 객체 리터럴 타입 검사를 수행 객체 리터럴을 강제할 때
잉여 속성 검사 우회 가능 (경고 무시) 잉여 속성 검사 적용 잉여 속성을 방지하면서 타입을 강제할 때
추론 보존 여부 강제된 타입으로 변경됨 원래 타입 유지 가능 타입 추론을 유지하면서도 타입 검증이 필요할 때

4. 결론

as를 사용하면 as는 타입 강제하기 때문에 타입이 넓어지거나, 잘못된 값이 허용되는 문제가 발생할 수 있습니다. satisfies객체의 타입을 검증하면서도, 값을 최대한 좁게 유지하여 타입 안정성을 높이는 데 도움을 줍니다.

즉, satisfies를 사용하면 기존 as보다 타입 안정성이 훨씬 좋아지고, 잘못된 키 추가나 불필요한 타입 확장을 방지할 수 있습니다. 

개발을 하시다 잉여 속성을 방지하면서 특정 타입을 만족해야 하는 경우 as나 복잡한 타입으로 해결해야 한다면 satisfies로 해결할 수 있는 문제일 수도 있습니다.