4.3 関数の部分型関係
関数型同士にも、オブジェクト型と同様に 部分型関係 が存在します。ある関数型 S が別の関数型 T の部分型であるとき、T 型の変数に S 型の関数を代入できます。
4.3.1 返り値の型による部分型関係
Section titled “4.3.1 返り値の型による部分型関係”返り値の型に基づく関係は、直感的な 共変 (covariant) の性質を持ちます。
- 条件: 引数リストが同じ場合、返り値の型が部分型であれば、その関数型自体も部分型となります。
- 具体例:
HasNameAndAge型を返す関数は、HasName型を返す関数として扱うことができます。これは「より詳細な情報を返す関数は、最低限の情報を期待する場所で代入可能である」ためです。
4.3.2 引数の型による部分型関係
Section titled “4.3.2 引数の型による部分型関係”引数の型に基づく関係は、直感とは逆の 反変 (contravariant) という性質を持ちます。
- 条件: 型
Sが型Tの部分型であるためには、引数の型において 「代入先の引数型が、代入する関数の引数型の部分型」 である必要があります。 - 理由: 関数を呼び出す側は、代入先の型定義に基づいて引数を渡します。代入される関数は、それよりも広い範囲の型(抽象的な型)を扱える必要があるためです。
- 具体例:
HasName(名前だけ持つ)を引数に取る関数は、HasNameAndAge(名前と年齢を持つ)を期待する変数に代入可能です。
4.3.3 引数の数による部分型関係
Section titled “4.3.3 引数の数による部分型関係”TypeScriptでは、引数の数が異なる関数同士でも特定の条件下で部分型関係が認められます。
- ルール: 引数が少ない関数は、引数が多い関数型として扱うことができます。
- 実用例:
Array.prototype.forEachのコールバック関数などが代表例です。本来は(value, index, array)の3つを受け取ることができますが、valueだけを受け取る関数を渡しても問題なく動作します。