TypeScript 4.9: The satisfies Operator. 翻訳+お手元
TypeScript 4.9から導入されたsatisfies
が公式のドキュメントを読んだだけでは直ぐに理解できなかったのでお手元で試した内容と共に整理してみました。
satisfies
オペレーター
TypeScriptの開発者はしばしばジレンマに直面します:ある表現が特定の型と一致することを確認したいが、推論の目的でその表現の最も具体的な型を保持したいとも思います。
例えば:
// 各プロパティは、文字列またはRGBタプルにすることができます。
const palette = {
red: [255, 0, 0],
green: "#00ff00",
bleu: [0, 0, 255]
// ^^^^ sacrebleu - タイポしてます!
};
// 'red'で配列メソッドを使えるようにしたい....
const redComponent = palette.red.at(0);
// または、'green'でstringメソッド...
const greenNormalized = palette.green.toUpperCase();
お手元
paletteの型推論
const palette: {
red: number[];
green: string;
bleu: number[];
}
redComponentの型推論
const redComponent: number | undefined
greenNormalizedの型推論
const greenNormalized: string
bleu
と書いていますが、おそらくblue
と書くべきでした。palette
に型注釈を使用してそのbleu
のタイポを捕捉しようとすることもできますが、各プロパティに関する情報を失ってしまいます。
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]
// ~~~~ タイプミスが正しく検出されるようになりました。
};
// しかし、ここで望ましくないエラーが発生しています - 「palette.red」は文字列"かもしれません"
const redComponent = palette.red.at(0);
お手元
paletteの型推論
const palette: Record<Colors, string | RGB>
redComponentの型推論
const redComponent: string | number | undefined
新しいsatisfies
オペレーターを使うと、表現の結果の型を変更することなく、ある表現の型が特定の型と一致することを検証できます。例として、palette
のすべてのプロパティがstring | number[]
と互換性があることを検証するためにsatisfies
を使用することができます。
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]
// ~~~~ タイプミスが発覚!
} satisfies Record<Colors, string | RGB>;
// これらの方法はどちらもまだ利用可能である!
const redComponent = palette.red.at(0);
const greenNormalized = palette.green.toUpperCase();
お手元
エラー箇所
paletteの型推論
const palette: {
red: [number, number, number];
green: string;
bleu: number[];
}
redComponentの型推論
const redComponent: number | undefined
greenNormalizedの型推論
const greenNormalized: string
satisfies
は多くの潜在的なエラーを捕捉するために使用することができます。例えば、あるオブジェクトが特定の型のすべてのキーを持っていることを保証するが、それ以上はないことを確認することができます:
type Colors = "red" | "green" | "blue";
// 'Colors'のキーが正確にあることを確認する.
const favoriteColors = {
"red": "yes",
"green": false,
"blue": "kinda",
"platypus": false
// ~~~~~~~~~~ error - "platypus"は'Colors'はリストされていませんでした.
} satisfies Record<Colors, unknown>;
// 'red'、'green'、'blue'プロパティに関するすべての情報が保持されています.
const g: boolean = favoriteColors.green;
お手元
エラー箇所
favoriteColorsの型推論
const favoriteColors: {
red: string;
green: boolean;
blue: string;
platypus: boolean;
}
おそらく、プロパティ名がどう一致するかについては気にしないかもしれませんが、各プロパティの型については気にしています。その場合、オブジェクトのすべてのプロパティ値がある型に適合することも確認することができます。
type RGB = [red: number, green: number, blue: number];
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0]
// ~~~~~~ error!
} satisfies Record<string, string | RGB>;
// 各プロパティに関する情報は依然として維持されています.
const redComponent = palette.red.at(0);
const greenNormalized = palette.green.toUpperCase();
お手元
エラー箇所
paletteの型推論
const palette: {
red: [number, number, number];
green: string;
blue: [number, number];
}
redComponentの型推論
const redComponent: number | undefined
greenNormalizedの型推論
const greenNormalized: string
より多くの例については、この提案をしたIssueと実装したプルリクエストをご覧いただけます。この機能の実装と反復に関わったOleksandr Tarasiukに感謝したいと思います。
出典:
Discussion