334

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 関数にパラメーターを追加しても、コンパイル エラーが発生します。アイデアをください。

4

6 に答える 6

282

TypeScript でオーバーロードすると、複数の署名を持つ 1 つの実装しかありません。

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

3 つのオーバーロードのみが、実際の実装ではなく、メソッド呼び出しの可能なシグネチャとして TypeScript によって認識されます。

あなたの場合、パラメーターに十分な共通性がないため、名前の異なる2つのメソッドを個人的に使用します。これにより、メソッド本体に何をすべきかを決定するために多くの「if」が必要になる可能性があります。

タイプスクリプト 1.4

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

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

の型aは「どちらstringnumber」です。

于 2012-11-03T19:50:31.303 に答える
238

これは、両方の関数が JavaScript にコンパイルされると、それらの署名が完全に同一になることが原因である可能性があります。JavaScript には型がないため、同じ数の引数を取る 2 つの関数を作成することになります。そのため、TypeScript では、そのような関数の作成が制限されています。

TypeScript はパラメーターの数に基づくオーバーロードをサポートしていますが、OO 言語と比較すると、従うべき手順が少し異なります。別の SO の質問への回答として、誰かが良い例で説明してくれました:メソッドのオーバーロード? .

基本的に、私たちがやっていることは、TypeScript がコンパイル エラーを出さないように、1 つの関数といくつかの宣言だけを作成することです。このコードを JavaScript にコンパイルすると、具体的な関数だけが表示されます。JavaScript 関数は複数の引数を渡して呼び出すことができるため、そのまま機能します。

于 2012-11-03T19:49:29.897 に答える
54

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

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フォームが隠されていることです。

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
于 2014-06-14T16:49:11.577 に答える