👀
関数型の互換性(戻り値)【個人学習まとめ】
関数型の互換性(共変)
関数型とは
関数の入力パラメータと戻り値を定義し、その関数構造を方として表現することです。
基本的な構文
let sampleFunction: (hikisu1: string, hikisu2: number) => boolean;
sampleFunctionは「string型の引数hikisu1とnumber型のhikisu2を受け取り、boolean型の値を返却する関数」となります。
戻り値の型
関数型の変数function1とfunction2を用意(引数は指定しない)。
それぞれ異なるオブジェクトを戻り値とする関数を代入します。
let function1 = () => ({ name: "太郎" });
let function2 = () => ({ name: "次郎", age: 20 });
function1はnameプロパティだけを持つオブジェクト、function2はnameプロパティとageプロパティを持つオブジェクトを返却します。
function1とfunction2を使って、関数の互換性を調査します。
互換性アリ
function1 = function2;
console.log(function1());
→{ name: '次郎', age: 20 }
function2の戻り値のオブジェクト型はfunction1の戻り値のオブジェクト型に必要なプロパティnameを保持しています。
そのため、fucntion2の戻り値の方はfunction1の戻り値のオブジェクトのサブタイプとなり、型の互換性の条件を満たすためfunction1にfunction2を代入することができます。
互換性ナシ
では、型の互換性がない場合はどうなるか確認してみます。
function2 = function1;
→ 型 '() => { name: string; }' を型 '() => { name: string; age: number; }' に割り当てることはできません。
プロパティ 'age' は型 '{ name: string; }' にありませんが、型 '{ name: string; age: number; }' では必須です。
エラーとなりました。
function2の戻り値のオブジェクト型はnameとageの2種類のプロパティを保持しています。
しかし、function1の戻り値のオブジェクト型はnameプロパティだけを保持しているため、function2の戻り値に必要なageプロパティが不足しています。
そのため安全に型を置き換えることができないため互換性がないとみなされてエラーとなります。
Discussion
互換性というよりは 変性の 共変 / 反変 でいうところの 共変ではないでしょうか?
ご指摘ありがとうございます!
ご紹介いただいた記事を読みました。確かに互換性ではなく、共変が正しいようですね。
学習に使っていた本が「互換性」という表現だったので、この記事では「互換性」を使っていました。
記事にも追記しておきます!