TypeScript 4.6 で追加された機能 代入したときの型推論の改善

こちらで書かれている内容です。

TypeScriptは、以下のようなオブジェクト型のユニオンを推論するときに、そのオブジェクトのキーを基に推論することができました。

type Action =
    | { kind: "NumberContents", payload: number }
    | { kind: "StringContents", payload: string };

function processAction(action: Action) {
    if (action.kind === "NumberContents") {
        // `action.payload` は number であると推論される
        let num = action.payload * 2
        // ...
    }
    else if (action.kind === "StringContents") {
        // `action.payload` は string であると推論される
        const str = action.payload.trim();
        // ...
    }
}

この例ではActionという型は、{ kind: “NumberContents", payload: number } と { kind: “StringContents", payload: string } のユニオンです。

そのため、以下のように推論できました。

  • kind プロパティが “NumberContents" という文字列なら payload の型は number
  • kind プロパティが “StringContents" という文字列なら payload の型は string

しかし、以下のように、action を変数に代入してしまうと、この推論はされなくなるのがこれまでの動作でした。

type Action =
    | { kind: "NumberContents", payload: number }
    | { kind: "StringContents", payload: string };

function processAction(action: Action) {
    const { kind, payload } = action; // ここで分割代入する
    if (kind === "NumberContents") {
        // payload は string | number と推論されてしまうので、型エラーになる
        let num = payload * 2
        // ...
    }
    else if (kind === "StringContents") {
        // payload は string | number と推論されてしまうので、型エラーになる
        const str = payload.trim();
        // ...
    }
}

TypeScript 4.6 以降では、分割代入しても kind の値によって payload の型を推論してくれます!

type Action =
    | { kind: "NumberContents", payload: number }
    | { kind: "StringContents", payload: string };

function processAction(action: Action) {
    const { kind, payload } = action;
    if (kind === "NumberContents") {
        // payload は number と推論されるので、型エラーにならない
        let num = payload * 2
        // ...
    }
    else if (kind === "StringContents") {
        // payload は string と推論されるので、型エラーにならない
        const str = payload.trim();
        // ...
    }
}