타입스크립트 4.9버전에서 satisfies 연산자가 추가되었습니다. 공식문서의 설명이 이해가 잘 안 가서 찬찬히 보다보니 이해가 되었습니다. 제가 이해한 내용을 설명해드리겠습니다.
일단 다음과 같은 객체의 타입을 선언 & 검사하고자 하는 상황입니다.
const palette = {
red: [255, 0, 0],
green: "#00ff00",
bleu: [0, 0, 255], // blue 오타
};
객체 키의 타입은 'red' | 'green' | 'blue'이고
객체 값의 타입은 [number, number, number] 또는 string 타입이니까 [number, number, number] | string이고,
객체니까 Record(사용법이 Record<객체키타입, 객체값타입>인거 아시죠?)를 사용해 다음과 같이
const palette: Record<'red' | 'green' | 'blue', [number, number, number] | string> = {
red: [255, 0, 0],
green: "#00ff00",
bleu: [0, 0, 255], // 오타 발견!
};
할 수 있습니다. 이러면 bleu의 오타는 잡힙니다.
다만, 속성을 사용할 때가 문제입니다. 타입스크립트는 그리 똑똑하지 않아서
const greenNormalized = palette.green.toUpperCase(); // property toUpperCase does not exist on type [number, number, number]
를 할 때 green이 string이라는 걸 못 잡아냅니다. 객체 값의 타입을 유니언으로 고정해놨기에 배열일 수도 있다고 생각하는 것이죠.
palette에 손을 올려 보면
const palette: Record<"red" | "green" | "blue", string | [number, number, number]>
로 타입이 고정되어 있습니다. 즉, green의 값도 string | [number, number, number]로 타입이 되어 있는 것이죠.
이래서 satisfies 연산자가 나왔다고 합니다.
const palette = {
red: [255, 0, 0],
green: "#00ff00",
bleu: [0, 0, 255],
};
처음에 값을 이렇게만 하면 red, green, bleu의 값 타입이 각각 배열, 문자열, 배열로 추론됩니다.
const palette: {
red: [number, number, number];
green: string;
bleu: [number, number, number];
}
타입 추론에 의해서죠. (bleu 오타 못 잡아내는 것은 덤)
이 이점을 누리면서 bleu 오타 검사도 할 방법이 없을까요?
그게 바로 satisfies 연산자입니다.
const palette = {
red: [255, 0, 0],
green: "#00ff00",
bleu: [0, 0, 255], // blue 오타
} satisfies Record<'red' | 'green' | 'blue', [number, number, number] | string>;
이렇게 할 수 있습니다.
이러면 palette의 타입은 타입 추론된 const 객체가 되면서 각각의 요소들은 Record 타입 선언한 것으로 다시 한 번 더 검사합니다. 여기서 bleu 오타가 걸리겠죠.
palette에 손을 올려보면 타입도 다음과 같이 개별적으로 적용되어 있습니다.
const palette: {
red: [number, number, number];
green: string;
blue: [number, number, number];
}
이제 속성도 에러없이 쓸 수 있습니다.
const greenNormalized = palette.green.toUpperCase();
처음 봤을 때는 뭐에 쓰는 건가 했던 satisfies 연산자. 바로 이 용도입니다. 객체 타입 검사용으로 자주 쓰게 될 것 같네요.