2017-09-20 23 views
0

TypeScriptコンパイラが私に悲しみを与えないようにするのに問題があります。私は、クラスのインスタンスではなくクラスの配列を持つコントローラを持っていますが、クラス自体です。これらのすべては、同じベース、UnitViewから拡張されます。 TitleViewもジェネリックを受け入れない場合は何らかの理由でエラーが発生しますが、エラーが発生した場合はエラーは発生しません。一般的なクラスのTypeScript配列

なぜTitleViewがモデルタイプを明示的にUnitViewに渡すので、ジェネリックスを受け入れる必要があるのか​​分かりません。誰かが私が間違っていることを説明したり見たりすることはできますか?

コード:

class Model { } 
class View<TModel extends Model> { 
    private model: TModel; 
} 

class UnitView<TModel extends Model> extends View<TModel> { } 

class TitleView extends UnitView<Model> { } 


class Controller { 
    private ViewClass: typeof UnitView; 

    private ViewClasses: typeof UnitView[] = [ 
     TitleView 
    ] 
} 

そしてhereあなたはそれをテストしたい場合は活字体の遊び場への直接リンクですが

答えて

2

エラーは、配列とは何の関係もありません。ここにあなたのバグの最小限の再現です:

class View<TModel> { 
    model: TModel; 
} 

class UnitView<TModel> extends View<TModel> { } 
class TitleView extends UnitView<{}> { } 

const example1: typeof UnitView = TitleView; // ERROR 

TileViewtypeof UnitViewに割り当てではありません。主な理由は、タイプ(汎用)は{}と互換性がないということです。

これは、以下に示すさらに簡略化例と同様である:

ジェネリックTとインスタンス(さえ{}

class Foo<T> { 
    model: T 
} 
class Bar{ 
    model: {} 
} 

const example2: typeof Foo = Bar; // ERROR 

TLDRは、割り当てのために互換性がありません。これは設計によるものです。互換性を保つための唯一の方法は、例えば、同様genericを維持ある

詳細

class Foo<T> { 
    model: T 
} 
class Bar<T>{ 
    model: T 
} 

const example3: typeof Foo = Bar; // Okay 

+0

だから私はのオフに拡張したクラスの配列になります配列を表現したい場合は、これを書くための正しい方法であるものユニットビュー? – jas7457

+0

ジェネリックを保存する必要があります。 'more'として答えるために追加されました – basarat

+0

TitleViewが本当にジェネリックを受け入れるべきではないので、別の方法があることを期待していました。それはその行の終わりであり、Modelはその時点で明確に定義されています。私はちょうど代わりに任意の配列に型を変更することがあります。このデザインは私には欠陥があるようですが、それを完全に理解していないかもしれません。助けてくれてありがとう。 – jas7457

0

がbasaratの答えを補完するために、ここで働くの宣言です:

private ViewClasses: (new (...args: any[]) => UnitView<{}>)[] = [ 
    TitleView 
] 
関連する問題