추가적인 타입 검사 satisfies 연산자

satisfies

타입 추론을 그대로 활용하면서 추가로 타입검사를 하고 싶을 때 사용

  • TS 4.9 버전에서 satisfies 연산자가 추가됨

  • 만족하다는 의미, 특정 객체 타입 검사용 으로 사용

  • 즉, 타입 선언이 아닌 추론된 타입에서 타입 검사를 하는 방법!!

// sirius 대신 sriius로 오타낸 상황

const universe = {
  sun: "star",
  sriius: "star", // sirius 오타
  earth: { type: "planet", parent: "sun" },
}

// key: sun | sriius | earth
// value: {type: string, parent: string } | string
  • 인덱스 시그니처를 사용해서 타이핑하면 sirius의 오타는 잡히게됨

const universe: {
  [key in 'sun' | 'sirius' | 'earth']: { type: string, parent: string } | string 
  } = {
    sun: "star",
    sriius: "star", // sirius 오타 잡힘
    earth: { type: "planet", parent: "sun" },
  }
}

속성 값을 사용할 때가 문제가 발생함

  • earth의 타입이 객체라는 것을 제데로 잡아내지 못한다.

universe.earth.type; 
// Property 'type' does not exist on type 'string | {type: string; parent: string;}',
// Property 'type' does not exist on type 'string'
  • 속성 값의 타입을 객체와 문자열의 유니언으로 표기했기 때문에 earth가 문자열일 수도 있다고 생각함

  • 즉, earth 도 string | {type: string, parent: string} 타입으로 인식하게됨

추론의 이점을 누리면서 오타를 잡아내는 방법

객체 리터럴 뒤에 'satisfies' 를 표기하면 된다.

  • 타입 추론된것을 그대로 사용하면서 각각의 속성들을 staisfies에 적은 타입으로 다시 한번 검사

const universe = {
  sun: "star",
  sriius: "star", // sirius 오타
  earth: { type: "planet", parent: "sun" },
}

// 추론된 타입 (정확하게 추론된다.)
const universe: {
  sun: string;
  sriius: string;
  earth: {
    type: string;
    parent: string;
  }
}
// satisfies 사용
const universe = {
  sun: "star",
  sriius: "star", // sirius 오타
  earth: {type: "planet", parent: "sun"},
} satisfies {
  [key in 'sun' | 'sirius' | 'earth']: { type: string, parent: string } | string 
}

Zerocho ver

  • 변수에 값을 제공을 했음에도 타입이 옵셔널이라 오류가 발생한다.

  • : NamedCircle 타입 선언을 지우면 객체의 유효성을 검사하지 못하므로 딜레마에 빠진다

  • 이럴 때 사용할 수 있는 것이 satisfies

type NamedCircle = {
  redius: number;
  name?: string;
}

const circle: NamedCircle = {radius: 1.0, name: 'woong'};

// circle.name은 optional type으로 undefined일 수 있기 때문에 오류 발생
console.log(circle.name.length);
type NamedCircle = {
  redius: number;
  name?: string;
}
// radius가 NamedCircle을 위반하여 오류 발생
const wrongCircle = {radius: '1.0', name: 'woong'};
	satisfies NamedCircle;

/* 객체 리터럴이 NamedCircle 타입과 일치하도록 보장되며
* 추론된 타입은 name 필드가 옵셔널이 아닌 필드가 된다.
*/
const circle = {radius: 1.0, name: 'woong'};
	satisfies NamedCircle;

// circle.name은 undefined가 될 수 없다.
console.log(circle.name.length);

Last updated