オーバーロードとは?
「関数に対して複数の型を定義すること」です。他言語のように、引数の異なる同名のメソッドを複数実装することはできません。あくまで一つのみ関数を実装するものになります。
メリット
「パラメータの型によって返り値の型が変わる関数」を表現できる。
基本的に他言語(Javaなど)のオーバーロードのメリットと同じと思って良いです。
末尾以外の引数の型を任意にする実装が可能
逆に言えば、末尾の引数のみがOptionalになる場合は、オーバーロードではなく、型にオプショナル指定するようにしましょう。
functionを使って書く方法
以下のように定義します。
1 2 3 4 5 |
function 関数名(引数:引数の型):戻り値 // シグネチャ1 function 関数名(引数1:引数の型,引数2:引数の型):戻り値 // シグネチャ2 function 関数名() { // 具体的な実装 } |
具体的には、以下のように記述します。
1 2 3 4 5 6 7 8 9 10 |
function test(arg1: number): number; function test(arg1: string, arg2: number): number; function test(arg1: string | number, arg2?: number) { if (typeof arg1 === "string" && arg2) return Number(arg1) + arg2; if (arg2) return Number(arg1) + arg2; return 0; } console.log("test(1)", test(1)); // 0 console.log("test(1,2)", test("1", 2)); // 3 |
functionを使った場合はアロー関数を使うことができないので注意です。
type、interfaceを使って書く方法
上記のコードをtypeを使って書き直すと以下のようになります。なお、typeで定義している個々の関数を「呼び出し可能オブジェクト(要は、関数そのものの型のことです。コールバック関数などを引数に渡す場合などに使用します。)」と呼ぶようです。
type版
1 2 3 4 5 6 7 8 9 10 11 12 13 |
type test = { (arg1: number): number; // 呼び出し可能オブジェクト1 (arg1: string, arg2: number): number; // 呼び出し可能オブジェクト2 }; const testfunc: test = (arg1: string | number, arg2?: number) => { if (typeof arg1 === "string" && arg2) return Number(arg1) + arg2; if (arg2) return Number(arg1) + arg2; return 0; }; console.log("test(1)", testfunc(1)); // 0 console.log("test(1,2)", testfunc("1", 2)); // 3 |
interface版
1 2 3 4 5 6 7 8 9 10 11 12 13 |
interface test { (arg1: number): number; (arg1: string, arg2: number): number; } const testfunc: test = (arg1: string | number, arg2?: number) => { if (typeof arg1 === "string" && arg2) return Number(arg1) + arg2; if (arg2) return Number(arg1) + arg2; return 0; }; console.log("test(1)", testfunc(1)); // 0 console.log("test(1,2)", testfunc("1", 2)); // 3 |
この方法であれば、アロー関数を使うことができます。
この記事へのコメントはありません。