generated at
satisfies operator
TypeScript v4.9で入った
V satisfies T と書いた時、
V: T を満たすかどうかをチェックしつつ、
V 自身の型推論を採用する
class における implements と同じ発想








ref
このrecordに型をつけることを考える
ts
const palette = { red: [255, 0, 0], green: "#00ff00", bleu: [0, 0, 255] // keyがtypoしている }
従来だと2通りの型の付け方があった
Record<K, T>を使う
ts
type Colors = "red" | "green" | "blue"; type RGB = [red: number, green: number, blue: number]; const palette: Record<Colors, string | RGB> = { red: [255, 0, 0], green: "#00ff00", bleu: [0, 0, 255] // error };
key のtypoは検出できる
しかし、 value の型が全て string|RGB になるので適切でない
as constを使う
ts
const palette = { red: [255, 0, 0], green: "#00ff00", bleu: [0, 0, 255] } as const;
value の差異は推論してくれる
しかし、 key にルールを課せないのでtypoしたまま気付けない
satisfies を使うことで解決する
ts
type Colors = "red" | "green" | "blue"; type RGB = [red: number, green: number, blue: number]; const palette = { red: [255, 0, 0], green: "#00ff00", bleu: [0, 0, 255] // error! } satisfies Record<Colors, string | RGB>; // これ
palette が、 Record<...> を満たすかどうかcheckしつつ、
palette は以下の型に推論される
ts
type Palette = { red: [number, number, number]; green: string; bleu: number[]; }




Record<string, string> で雑に型を付ける時も従来より便利になった
従来: 型推論がしょぼくなる
satisfies
ちゃんと推論してくれるので補完できる
as const satisfies Tを使うともっと厳格になる



他の実用例はこの記事が良かった
as const satisfies Tをうまく使っている



recordに対してしか使えない?
そんなことはないmrsekut
タプルに対して使う例
ts
type Option = { type: 'a' } | { type: 'b' } | { type: 'c' }; type Type = Option['type']; const options = ['a', 'b', 'c'] satisfies Type[];
普通に opstions: Type[] で型付けすると、 ['a','a','a'] なども許容してしまう
as const すると、 ['a','b','hoge'] のように誤字ったときに検出できない
['a', 'b', 'c'] というタプルがほしい