tips chips

日々の作業で出てきた技術メモの切れ端を置いておくページ

TypeScript の satisfies オペレータについて

何が便利なのか分かってなかったので改めて確認してみたメモ

※ほとんど以下の翻訳のようなものなのでドキュメントを読んでもらった方が正確です

Documentation - TypeScript 4.9
TypeScript 4.9 Release Notes
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator

ある式がある型にマッチすることを保証したいが、一方で推論結果も保持したいというケースに使えるもの、と書いている

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] // ~~~~ The typo is now correctly detected }; // But we now have an undesirable error here - 'palette.red' "could" be a string. const redComponent = palette.red.at(0);

blueをtypoしていることを検知できているので良さげに見えるが、palette.redがtupleであるという型推論の結果が失われてしまっている。

そこでsatisfiesオペレーターを使うと型推論の結果を変えずに指定した型を満たしているかをvalidateすることができる。

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] // ~~~~ The typo is now caught! } satisfies Record<Colors, string | RGB>; // Both of these methods are still accessible! const redComponent = palette.red.at(0); const greenNormalized = palette.green.toUpperCase();

先ほどとは違い、palette.redがtupleであるという型情報は失われていないし、blueのtypoも検知できている。

type Colors = "red" | "green" | "blue"; // Ensure that we have exactly the keys from 'Colors'. const favoriteColors = { "red": "yes", "green": false, "blue": "kinda", "platypus": false // ~~~~~~~~~~ error - "platypus" was never listed in 'Colors'. } satisfies Record<Colors, unknown>; // All the information about the 'red', 'green', and 'blue' properties are retained. const g: boolean = favoriteColors.green;

このように Record<Colors, unknown>を満たす、という条件にしてやると、プロパティの検査だけをすることができる。型推論の結果には影響を与えないので、greeenがbooleanの値であるという情報はそのまま使える。