関数のオーバーロードとは?
関数のオーバーロード(Function Overloading)とは、同じ名前の関数を異なる引数の型や数で複数定義し、呼び出し時の引数に応じて適切な関数が実行されるようにすることを指します。TypeScriptでは、オーバーロードシグネチャを使ってこれを実現します。
基本構文
TypeScriptでの関数のオーバーロードは、以下のように定義します:
- オーバーロードシグネチャ:関数の異なるバージョンを定義します。
- 実装シグネチャ:実際の関数実装です。これは関数の実際のロジックを含み、オーバーロードシグネチャの条件をすべて満たす必要があります。
例1: 数値の合計と文字列の結合
以下の例では、引数の数や型に応じて異なる操作を行う関数を定義しています。
// オーバーロードシグネチャ
function combine(a: number, b: number): number;
function combine(a: string, b: string): string;
// 実装シグネチャ
function combine(a: number | string, b: number | string): number | string {
if (typeof a === "number" && typeof b === "number") {
return a + b;
} else if (typeof a === "string" && typeof b === "string") {
return a + b;
} else {
throw new Error("Invalid arguments");
}
}
// 使用例
console.log(combine(1, 2)); // 出力: 3
console.log(combine("hello", "world")); // 出力: "helloworld"
// console.log(combine(1, "hello")); // エラー: Invalid arguments
例2: 配列要素の結合
次に、配列要素を結合する関数の例です。
// オーバーロードシグネチャ
function merge(a: number[], b: number[]): number[];
function merge(a: string[], b: string[]): string[];
// 実装シグネチャ
function merge(a: number[] | string[], b: number[] | string[]): number[] | string[] {
return a.concat(b);
}
// 使用例
console.log(merge([1, 2], [3, 4])); // 出力: [1, 2, 3, 4]
console.log(merge(["hello"], ["world"])); // 出力: ["hello", "world"]
オーバーロードの仕組み
1. オーバーロードシグネチャ:
- 最初に、異なる引数の型や数に応じた関数シグネチャを定義します。
- これらのシグネチャは実装の上部に書き、関数がどのような引数で呼び出されるかを定義します。
2. 実装シグネチャ:
- 実際の関数定義はすべての可能な引数型をカバーする必要があります。
- 実装内で引数の型チェックを行い、適切な処理を実行します。
注意点
1. 実装シグネチャはオーバーロードシグネチャと一致しないこと:
- 実装シグネチャは、オーバーロードシグネチャで定義されたすべての引数型を包含する必要があります。
- 実装シグネチャの引数はユニオン型として定義することが一般的です。
2. TypeScriptの型推論を利用すること:
- TypeScriptの型推論により、オーバーロードシグネチャを適切に定義することで、IDEやエディタでの型補完や型チェックが効果的に行われます。
まとめ
関数のオーバーロードは、同じ名前の関数を引数の型や数に応じて異なるバージョンを提供するための機能です。これにより、コードの柔軟性と可読性が向上し、さまざまな入力に対して適切な処理を行う関数を効率的に定義できます。