🫥

TypeScript 4.9: The satisfies Operator. 翻訳+お手元

2024/01/07に公開

TypeScript 4.9から導入されたsatisfies公式のドキュメントを読んだだけでは直ぐに理解できなかったのでお手元で試した内容と共に整理してみました。

satisfies オペレーター

TypeScriptの開発者はしばしばジレンマに直面します:ある表現が特定の型と一致することを確認したいが、推論の目的でその表現の最も具体的な型を保持したいとも思います。

例えば:

.ts
// 各プロパティは、文字列または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のタイポを捕捉しようとすることもできますが、各プロパティに関する情報を失ってしまいます。

.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]
//  ~~~~ タイプミスが正しく検出されるようになりました。
};
// しかし、ここで望ましくないエラーが発生しています - 「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を使用することができます。

.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]
//  ~~~~ タイプミスが発覚!
} 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は多くの潜在的なエラーを捕捉するために使用することができます。例えば、あるオブジェクトが特定の型のすべてのキーを持っていることを保証するが、それ以上はないことを確認することができます:

.ts
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;
}

おそらく、プロパティ名がどう一致するかについては気にしないかもしれませんが、各プロパティの型については気にしています。その場合、オブジェクトのすべてのプロパティ値がある型に適合することも確認することができます。

.ts
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に感謝したいと思います。

出典:
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-9.html#the-satisfies-operator

Discussion