JavaやC#のような言語では、関数やメソッドのオーバーロードは標準的な機能であり、同じ名前の関数を異なる引数で複数宣言できます。しかし、JavaScriptにはそれがなく、潜在的なエラーを引き起こす可能性があります。TypeScriptはこの問題を型レベルで解決します。
TypeScriptには実際のオーバーロード(複数の実装)は存在しません。複数の関数シグネチャを宣言できますが、実際の関数は1つだけです。宣言されたシグネチャと実装の間に不整合がある場合や、シグネチャの位置付けが間違っている場合にエラーが発生します。
TypeScriptは、複数のシグネチャを宣言し、その全てのオーバーロードバリエーションと互換性のある単一の実際の実装を通じて、関数のオーバーロードをサポートします。
コードの例:
function sum(a: number, b: number): number; function sum(a: string, b: string): string; function sum(a: any, b: any): any { return a + b; } const a = sum(1, 2); // 3 const b = sum('foo', 'bar'); // "foobar"
主な特徴:
すべてのオーバーロードのシグネチャを宣言する前に関数の実装を定義できますか?
いいえ、最初にすべてのオーバーロードのシグネチャを宣言し、その後に実装を記述する必要があります。エラー:
// エラー!最初にシグネチャ、その後に実装 function foo(a: number): number { return a } // エラー function foo(a: string): string { return a } // エラー
TypeScriptはすべてのオーバーロードのシグネチャで返り値の型をチェックしますか?
TypeScriptはコンパイル時に宣言されたシグネチャに従って返り値の型を保証しますが、実行時には型のチェックは行われません。
実装内でのすべての入力データのバリエーションをカバーする必要がありますか?
実装する関数は、オーバーロードのシグネチャに従ってすべての入力データのバリエーションを適切に処理する必要があります:
function parse(a: number): string; function parse(a: string): string; function parse(a: number | string): string { return String(a); }
異なる入力型の複数の関数のオーバーロードが宣言されていますが、実装がすべてのケースを処理せず、まれな入力に対してランタイムでエラーをスローします。
利点:
欠点:
関数の各オーバーロードが実装内での型に対する条件でカバーされており、型チェック(typeof/instanceof)が使用されています。
利点:
欠点: