web-dev-qa-db-ja.com

TypeScript関数のオーバーロード

TypeScript言語仕様のセクション6.3は、関数のオーバーロードについて説明し、これを実装する方法の具体例を示しています。しかし、私がこのようなことを試みるならば:

export class LayerFactory { 

    constructor (public styleFactory: Symbology.StyleFactory) { }

    createFeatureLayer (userContext : Model.UserContext, mapWrapperObj : MapWrapperBase) : any {           
         throw "not implemented";
    }                 

    createFeatureLayer(layerName : string, style : any) : any {
        throw "not implemented";
     }        

}

関数パラメータの型が異なっていても、識別子が重複していることを示すコンパイラエラーが発生します。 2番目のcreateFeatureLayer関数に追加のパラメータを追加しても、コンパイラエラーが発生します。考えてください。

196
Klaus Nji

これは、両方の関数がJavaScriptにコンパイルされたときに、それらのシグネチャがまったく同じであるためかもしれません。 JavaScriptには型がないので、同じ数の引数を取る2つの関数を作成することになります。そのため、TypeScriptでは、このような関数を作成することはできません。

TypeScriptはパラメータ数に基づくオーバーロードをサポートしていますが、OO言語と比較した場合、従うべきステップは少し異なります。他のSO質問に答えて、誰かがそれをいい例で説明しました: Method overloading?

基本的には、TypeScriptでコンパイルエラーが発生しないように、1つの関数と多くの宣言を作成しています。このコードをJavaScriptにコンパイルすると、具象関数だけが表示されます。 JavaScript関数は複数の引数を渡すことで呼び出すことができるので、それだけで動作します。

161
S. Ravi Kiran

TypeScriptでオーバーロードすると、複数のシグネチャを持つ実装は1つだけになります。

class Foo {
    myMethod(a: string);
    myMethod(a: number);
    myMethod(a: number, b: string);
    myMethod(a: any, b?: string) {
        alert(a.toString());
    }
}

TypeScriptでは、3つのオーバーロードだけがメソッド呼び出しのシグネチャとして認識され、実際の実装では認識されません。

あなたのケースでは、私は個人的に異なる名前を持つ2つのメソッドを使用するでしょう。それは、パラメータ本体には十分な共通点がないからです。

TypeScript 1.4

TypeScript 1.4では、通常、共用体型を使用してオーバーロードの必要性を取り除くことができます。上記の例は、次の式を使ってよりよく表現できます。

myMethod(a: string | number, b?: string) {
    alert(a.toString());
}

aの型は "stringまたはnumber"です。

176
Fenton

関数を複数の呼び出しシグネチャを持つ型を持つものとして宣言することで、オーバーロードされた関数を宣言することができます。

interface IFoo
{
    bar: {
        (s: string): number;
        (n: number): string;
    }
}

それでは、

var foo1: IFoo = ...;

var n: number = foo1.bar('baz');     // OK
var s: string = foo1.bar(123);       // OK
var a: number[] = foo1.bar([1,2,3]); // ERROR

関数の実際の定義は単数形でなければならず、その引数に対して内部で適切なディスパッチを実行します。

たとえば、クラスを使用すると(これはIFooを実装できますが、必須ではありません)。

class Foo
{
    public bar(s: string): number;
    public bar(n: number): string;
    public bar(arg: any): any 
    {
        if (typeof(arg) === 'number')
            return arg.toString();
        if (typeof(arg) === 'string')
            return arg.length;
    }
}

ここで興味深いのは、anyの形式が、より具体的に型指定されたオーバーライドによってhiddenであるということです。

var foo2: new Foo();

var n: number = foo2.bar('baz');     // OK
var s: string = foo2.bar(123);       // OK
var a: number[] = foo2.bar([1,2,3]); // ERROR
38
Drew Noakes

他の人たちへの頭脳として、少なくともWebPackによってAngular 2のためにコンパイルされたTypeScriptによって明らかにされるように、あなたはoverLOADEDメソッドの代わりに静かにoverWRITTENを得ます。

myComponent {
  method(): { console.info("no args"); },
  method(arg): { console.info("with arg"); }
}

お電話:

myComponent.method()

引数なしでメソッドを実行し、引数なしのバージョンを黙って無視して出力します。

with arg
1
mtyson