2016-07-29 8 views
1

私はTypeScriptの特殊な関数シグネチャを扱っています。TypeScriptの特殊な関数シグネチャ

// Basic superclass and subclass 
class Model { } 
class Product extends Model { name: string; } 

// Define interface for singleton factory class with generic create method. 
interface IModels { create(type: any): Model; } 

const ctors = {product: Product}; 

// Implement generic version of create. 
class Models implements IModels { 
    create(type: any): Model { return new ctors[type](); } 
} 

// Extend interface with specialized signature. 
interface IModels { create(type: "product"): Product; } 

const models = new Models; 

const product: Product = models.create("product"); 

はしかし、これが最後の行に次のエラーが得られます:私の理解では、次のように動作するはずということです

Class 'Models' incorrectly implements interface 'IModels'. 
    Types of property 'create' are incompatible. 
    Type '(type: any) => Model' is not assignable to type '{ (type: any): Model; (type: "product"): Product; }'. 
     Type 'Model' is not assignable to type 'Product'. 
     Property 'name' is missing in type 'Model'. 

私はその後、anyからModelからcreateの戻り値の型を変更した場合は、それコンパイルするが、なぜそれをしなければならないのだろうか? any"product"許容可能な実装であるため

答えて

1

インターフェース...

interface IModels { create(type: "product"): Product; } 

は...メソッドシグネチャ...

create(type: any): Model; 

してModelsクラスに実装されています。コンパイラは、Modelsクラスのメソッド情報のみを使用します。あなたはまた、過負荷署名に同様にあなたのModelsクラスにこの情報を追加して、エラーを取り除くことができ

:動作するようになっていますどのように私の理解ではありません

class Models implements IModels { 
    create(type: "product"): Product; 
    create(type: any): Model; 
    create(type: any): Model { 
     return new ctors[type](); 
    } 
} 
+0

。型の特定の値を持つ追加の宣言は、関数が型 '' product ''で呼び出されたときに、型 ''の値を返すことを明示しています。 [TS docs](https://www.typescriptlang.org/docs/handbook/declaration-merging.html)は、 'interface Document {createElement(tagName:" div "):HTMLDivElement;'の例を示しています。これは、TS 'document.createElement'がパラメータ" div "で呼び出されたとき、戻り値は' HTMLDivElement'なので、すべてが機能します。 –

+0

@torazaburo申し訳ありませんが、第2のインターフェイスに気付かなかった。私は自分の答えを更新しました。 –

関連する問題