2017-05-03 7 views
1

Telerikの剣道UIクラスの1つ、Windowウィジェットを拡張しようとしています。私はTypeScript 2.2.2を使用しています。TypeScriptの剣道UIウィンドウを拡張する

参考のため、これはWindowの定義と同じです。私はこの質問に関連する部分だけを含める。

class Window extends kendo.ui.Widget { 
    static extend(proto: Object): Window; 
    constructor(element: Element, options?: WindowOptions); 
    content(): string; 
    content(content?: string): kendo.ui.Window; 
    content(content?: JQuery): kendo.ui.Window; 
} 

content(string)メソッドをオーバーライドします。私はthis exampleを私のコードの基礎として使用しています。だから私は、次があります。

export class AngularizedWindow extends kendo.ui.Window { 
    constructor(element: Element, options?: kendo.ui.WindowOptions) { 
     super(element, options); 
    } 

    content(content?: string) : kendo.ui.Window { 
     console.log("Setting content"); 
     return super.content(content); 
    } 
} 

しかし、それは私に、このエラーを与える:私は間違って

ts\widgets\AngularizedWindow.ts(2,18): error TS2415: Class 'AngularizedWindow' incorrectly extends base class 'Window'.
Types of property 'content' are incompatible.
Type '(content?: string) => Window' is not assignable to type '{(): string; (content?: string): Window; (content?: JQuery): Window; }'.
Type 'Window' is not assignable to type 'string'.

何をしているのですか?このエラーをどのように解釈するのか分かりません。適切にフォーマットされたエラーメッセージ、中タイプ

答えて

1

「に割り当てていない」、そう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.

+0

だから、私は私のクラスに(任意の実装なし)3つのオーバーロードを追加する必要があり、その後、追加します'content()'の実装メソッド?そうですか? – Amy

+0

はい。答えに例を追加しました。 – artem

関連する問題