「に割り当てていない」、そうcallable signaturesと呼ばれる3を有するタイプだ
{
(): string;
(content?: string): Window;
(content?: JQuery): Window;
}
あり、それは3のいずれかの方法で呼び出すことができる何かを説明します。引数なし
- 、オプションのjQueryのargumeでウィンドウ
- を返して、任意の文字列引数を文字列
- を返しますNT、typescriptですが、関数のオーバーロードを表し方法のウィンドウ
返す - 剣道Window
で宣言されているように、それは3つのオーバーロードされたバリアントを持っているので、それは、content
の実際の型だが:
content(): string;
content(content?: string): kendo.ui.Window;
content(content?: JQuery): kendo.ui.Window;
Javascriptが関数のオーバーロードを持っていません、だから、typescriptはできるだけそれをシミュレートすることができますし、オーバーロードされたメソッドを使用しているときにはうまく動作します。
しかし、オーバーロードされたメソッドを実装(またはオーバーライド)するときは、typescriptは役に立ちません。 1つの実装のみを持つことができ、実行時にすべての引数の組み合わせを処理する必要があります。だからあなたの拡張クラスはcontent()
のすべてのオーバーロードされた宣言を繰り返し、ここでの例で説明したように、宣言されたすべての変異体およびそれらのすべてを扱うことができると互換性のある実装を提供しなければならない:https://www.typescriptlang.org/docs/handbook/functions.html#overloads
私は剣道UI経験がないので、
base.ts
export class Widget {}
export class Element {}
export class WindowOptions {}
export class JQuery {}
export namespace kendo {
export namespace ui {
export class Window extends Widget {
static extend(proto: Object): Window {return null}
constructor(element: Element, options?: WindowOptions) { super() }
content(): string;
content(content?: string): Window;
content(content?: JQuery): Window;
content(content?: string | JQuery): Window | string {
return null;
}
}
}
}
D:私はちょうどtypescriptです2.3およびNode.jsの中の実行でコンパイル問題のコードに基づいて、最小限の例を作りました。TS
import { WindowOptions, JQuery, kendo } from './base';
export class AngularizedWindow extends kendo.ui.Window {
constructor(element: Element, options?: WindowOptions) {
super(element, options);
}
content(): string;
content(content?: string): kendo.ui.Window;
content(content?: JQuery): kendo.ui.Window;
content(content?: string | JQuery) : kendo.ui.Window | string {
if (typeof content === 'undefined') {
console.log('implementation 1');
return super.content();
} if (typeof content === 'string') {
console.log('implementation 2');
return super.content(content);
} else { // ought to be jQuery
console.log('implementation 3');
return super.content(content);
}
}
}
let a = new AngularizedWindow(null);
a.content();
a.content('b');
a.content({});
コンパイルと実行
./node_modules/.bin/tsc base.ts d.ts
node d.js
それは、今
implementation 1
implementation 2
implementation 3
を印刷しますが、サンプルコードを見ると、それは質問を頼む:content()
は本当にこれらすべての過負荷に必要ありません宣言?実装のように見えます。これは、共用体型をとり、共用体型を戻すもので、すべての使用例を処理するのに十分です。
しかし、過負荷なしに、このコードはコンパイルされません:
let s: string = a.content();
エラー:
d.ts(32,5): error TS2322: Type 'string | Window' is not assignable to type 'string'.
Type 'Window' is not assignable to type 'string'.
をので、オーバーロードは、引数の型と戻り値の型との間の関係を記述することができます。しかし、この関係は実装ではコンパイラによって強制されません。それはthis comment by one of typescript developersで表現されるような過負荷によって導入された追加の複雑さは、それだけの価値があるかどうか議論の余地があります:私はあなたを理解していた場合
Realistically, JavaScript does not have function overloading and in general I advise people to just not use overloading at all. Go ahead and use union types on parameters, but if you have multiple distinct behavioral entry points, or return types that differ based on inputs, use two different functions! It ends up being clearer for callers and easier for you to write.
だから、私は私のクラスに(任意の実装なし)3つのオーバーロードを追加する必要があり、その後、追加します'content()'の実装メソッド?そうですか? – Amy
はい。答えに例を追加しました。 – artem