Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TypeScriptの次なる大進化なるか!? 条件型を返り値とする関数の型推論

uhyo
November 16, 2024

 TypeScriptの次なる大進化なるか!? 条件型を返り値とする関数の型推論

2024-11-16 TSKaigi Kansai 2024

uhyo

November 16, 2024
Tweet

More Decks by uhyo

Other Decks in Technology

Transcript

  1. 今回使う例 この例を通して新機能の使い方を解説します function takeFirst( left: number | undefined, right: number

    | undefined, ): number | undefined { return left ?? right; } (あまり意味のない例ですがもっと意味ある例を簡略化したと思ってください) 8
  2. 返り値の型を改良する function takeFirst( left: number | undefined, right: number |

    undefined, ): number | undefined { return left ?? right; } 9 undefinedが返るのはleftもrightも undefinedな場合だけだから、 それを型に反映したい
  3. 返り値の型を改良する function takeFirst< Left extends number | undefined, Right extends

    number | undefined > ( left: number | undefined, right: number | undefined, ): Left extends number ? number : Right extends number ? number : number | undefined { return left ?? right as any; } 10
  4. 返り値の型を改良する function takeFirst< Left extends number | undefined, Right extends

    number | undefined > ( left: number | undefined, right: number | undefined, ): Left extends number ? number : Right extends number ? number : number | undefined { return left ?? right as any; } 11 LeftかRightがnumberなら 返り値はnumber
  5. 返り値の型を改良する function takeFirst< Left extends number | undefined, Right extends

    number | undefined > ( left: number | undefined, right: number | undefined, ): Left extends number ? number : Right extends number ? number : number | undefined { return left ?? right as any; } 12 TSの新機能の力で asの使用を消したい!
  6. 新機能の制約 T extends A ? AType : T extends B

    ? AType : never • ある型引数Tに対して、条件を繰り返し確認する形になっている • Tは特定の引数の型である • ATypeやBTypeはTの制約(constraint)である • constraint: 型引数定義のT extends FooのFooのこと • どの条件にも当てはまらなった場合はneverにする • Tの型がランタイムの値よりも緩い場合があり条件型のfalse側は情報量がないため 14
  7. 返り値の型を制約を満たすようにする function takeFirst< Left extends number | undefined, Right extends

    number | undefined > ( left: number | undefined, right: number | undefined, ): Left extends number ? number : Right extends number ? number : number | undefined { return left ?? right as any; } 15 条件を満たしていない • 複数の型引数が条件に 含まれている • 最後がneverではない
  8. 返り値の型を制約を満たすようにした function takeFirst< Left extends number | undefined, Right extends

    number | undefined > ( left: number | undefined, right: number | undefined, ): Right extends number ? number : Right extends number | undefined ? Left : never { return left ?? right as any; } 16 • Rightだけで条件を記述 • 最後をneverにした
  9. 実装も推論可能な形に直した function takeFirst< Left extends number | undefined, Right extends

    number | undefined > ( left: number | undefined, right: number | undefined, ): Right extends number ? number : Right extends number | undefined ? Left : never { if (right !== undefined) return left ?? right; return left; } 18
  10. 実装も推論可能な形に直した function takeFirst< Left extends number | undefined, Right extends

    number | undefined > ( left: number | undefined, right: number | undefined, ): Right extends number ? number : Right extends number | undefined ? Left : never { if (right !== undefined) return left ?? right; return left; } 19 条件型の分岐と同じように rightで分岐することで 型チェックが通った