TypeScriptでは、オーバーロードメソッドを定義できますが、オブジェクトリテラルにはオーバーロードメソッドを書くことができません。例えば、次のコードはbar
メソッドを複数定義しようとする例ですが、コンパイルエラーになります。
// コンパイルエラーになるコードです
const Foo = {
bar(value: number): number
bar(value: string): string
bar(value: any): any {
return value
}
}
この問題は、こちらのTypeScript Playgroundで再現できます。
クラスでのオーバーロード: TypeScriptのオーバーロードの書き方の基本については、以前「オーバーロードメソッドを定義する方法」で説明したのでご覧ください。今回問題にするのは、クラスでのオーバーロードではなく、オブジェクトリテラルでオーバーロードのやりかたです。
オブジェクトリテラルでオーバーロードメソッドを作る方法
では、オブジェクトリテラルでオーバーロードメソッドを定義するにはどうしたらいいのでしょうか? 解決策が2つあります。ひとつずつ見ていきましょう。
解決策1: interface
を定義する
ひとつめの解決策は、interface
を定義する方法です。この方法では、オーバーロードメソッドの宣言はinterface
に書き、実装はオブジェクトリテラルに書きます。
interface FooInterface {
bar(value: number): number
bar(value: string): string
}
const Foo: FooInterface = {
bar(value: any): any {
return value
}
}
この方法では、クラスのオーバーロードの書き方と異なり、オーバーロードの定義が実装と離れてしまうことがあるものの、ハックのないストレートなコードになります。
解決策2: 匿名クラスを使う
ふたつめの解決策は、匿名クラスを使う方法です。この方法は、オーバーロードメソッドの宣言と実装は、同じ匿名クラスに書くことができます。
const Foo = new class {
bar(value: number): number
bar(value: string): string
bar(value: any): any {
return value
}
}
匿名クラスを使うため、ハック感がいなめないコードになりますが、オーバーロードの定義と実装が一箇所で管理できるというメリットはあります。