2017-09-20 2 views
0

Je n'arrive pas à faire en sorte que le compilateur TypeScript ne m'attriste pas. J'ai un contrôleur qui a un tableau de classes, pas l'instance de la classe, mais la classe elle-même. Tout cela va s'étendre de la même base, UnitView. Pour une raison quelconque, je reçois une erreur si mon TitleView n'accepte pas les génériques, mais je ne reçois aucune erreur si c'est le cas.Tableau TypeScript de classes génériques

Je ne comprends pas pourquoi TitleView aurait besoin d'accepter des génériques car il transmet explicitement le type de modèle au UnitView. Quelqu'un peut-il expliquer ou voir quelque chose que je fais mal?

code:

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 
    ] 
} 

Et here est un lien direct vers aire de jeux tapuscrit si vous voulez le tester, il

Répondre

2

L'erreur n'a rien à voir avec les tableaux. Voici une reproduction minimale de votre bug:

class View<TModel> { 
    model: TModel; 
} 

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

const example1: typeof UnitView = TitleView; // ERROR 

TileView est pas assignable à typeof UnitView. La raison principale étant que le type de T (un générique) ne sont pas compatibles avec {}.

Ceci est similaire à la plus simplifiée exemple ci-dessous:

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

const example2: typeof Foo = Bar; // ERROR 

TLDR

Generics T et les instances (même {}) ne sont pas compatibles pour l'affectation. C'est par conception.

Plus

La seule façon de rester compatible est la chasse gardée du generic ainsi par exemple

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

const example3: typeof Foo = Bar; // Okay 
+0

Alors, quelle serait la bonne façon d'écrire ce que je veux exprimer le tableau sera un tableau de classes qui se prolongent hors de UnitView? – jas7457

+0

Vous devrez conserver le générique. Ajouté pour répondre comme 'more' – basarat

+0

J'espérais qu'il y aurait un autre moyen, car TitleView ne devrait vraiment pas accepter les génériques, car c'est la fin de la ligne et le modèle est bien défini à ce moment-là. Je peux juste changer les typings à un tableau de n'importe où à la place. Cette conception me semble imparfaite, ou peut-être que je ne comprends pas tout à fait. Merci pour l'aide. – jas7457

0

Pour compléter la réponse de basarat, voici une déclaration de travail:

private ViewClasses: (new (...args: any[]) => UnitView<{}>)[] = [ 
    TitleView 
]