オーバーロード関数(Function Overloading)
オーバーロード関数とは、同じ名前で引数の型や戻り値の型が異なる複数の関数シグネチャをもつ関数のことです。
文字だけツラツラと並べられても、何のことやらと頭の上に?を浮かべる人もいると思いますので、さっそく例をお見せしたいと思います。
// オーバーロード関数
function multipleA(a: number, b: number): number; // 関数シグネチャ1
function multipleA(a: string, b: number): string; // 関数シグネチャ2
function multipleA(a: any, b: any): any {
if (typeof a === "number" && typeof b === "number") {
return a * b;
} else {
return a.repeat(b);
}
}
console.log(multipleA(2, 2)); // 出力1:4(number型)
console.log(multipleA("hello", 2)); // 出力2:'hellohello'(string型)
// オーバーロード関数を使用しない場合
function multipleB(a: number | string, b: number): number | string {
if (typeof a === "number") {
return a * b;
} else if (typeof a === "string") {
return a.repeat(b);
} else {
return "";
}
}
console.log(multipleB(2, 2)); // 出力1:4(numberとstringのユニオン型)
console.log(multipleB("hello", 2)); // 出力2:'hellohello'(numberとstringのユニオン型)
例では、オーバーロード関数「multipleA」とそうでない関数「multipleB」を定義しました。
「multipleA」は、以下の2つの関数シグネチャがあります。
関数シグネチャ 1: 2 つの number 型の引数を受け取り、number 型の値を返す
関数シグネチャ 2: string 型と number 型の引数を受け取り、string 型の値を返す
一方、「multipleB」は、2 つの引数を受け取りますが、第一引数は number と string のユニオン型、第二引数は number 型となり、number と string のユニオン型の値を返します。
オーバーロード関数の素晴らしいところ
さて、2つの関数を引き合いに出しましたが、オーバーロード関数の魅力をお伝えしたいと思います。
結論から言うと、オーバーロード関数は、引数の型に応じて戻り値の型を推論します。
どういういことかと言いますと、「multipleA」の出力1、出力2はそれぞれ『string 型』、『number 型』の値を返すようになっています。
しかし、「multipleB」の出力1、出力2はどちらも『number と string のユニオン型』の値を返すため、戻り値が string 型なのか number 型なのか明示的に決まっているわけではありません。なので、もし、「multipleB」の戻り値を他の処理で使用したいときには、また型ガードをしなければならないケースが生じてきます。
ぜひ、Typescript の公式 Playground で、実際にどうなっているか確認してみてください。