2017-10-06 9 views
0

Je voudrais mélanger certaines méthodes à une classe de base abstraite, pour créer une nouvelle classe abstraite.Mixage en classe de base abstraite dans Typescript

Prenons l'exemple suivant:

abstract class Base { 
    abstract method(); 
} 

interface Feature { 
    featureMethod(); 
} 

class Implementation extends Base implements Feature { 
    method() { 
    } 

    featureMethod() { 
     // re-usable code that uses method() call 
     this.method(); 
    } 
} 

Cela fonctionne très bien, mais l'objectif est de prendre les mises en œuvre de l'interface Feature et le déplacer vers un mixin il peut être réutilisé par d'autres implémentations du Classe de base

Je suis arrivé à ce qui suit, mais il ne compile pas dactylographiée 2.4.1

type BaseConstructor<T = Base > = new (...args: any[]) => T; 
export function MixFeature<BaseType extends BaseConstructor>(TheBase: BaseType) { 
    abstract class Mixed extends TheBase implements Feature { 
     featureMethod() { 
      // re-usable code that uses method() call 
      this.method(); 
     } 
    } 
    return Mixed; 
} 

class Implementation extends MixFeature(Base) { 
    method() { 
    } 
} 

Mais Tapuscrit ne l'approuve pas, en disant:

Error:(59, 41) TS2345:Argument of type 'typeof Base' is not assignable to parameter of type 'BaseConstructor<Base>'. 
Cannot assign an abstract constructor type to a non-abstract constructor type. 

Est-il possible de faire cette travailler ou est-ce une limitation Typescript que les bases abstraites ne peuvent pas être étendues en utilisant des mixins?

Répondre

0

Il n'existe actuellement aucun moyen de décrire le type d'un constructeur de classe abstraite dans TypeScript. GitHub Issue Microsoft/TypeScript#5843 suit cela. Vous pouvez y chercher des idées. Une suggestion est que vous pouvez supprimer l'erreur en affirmant simplement que Base est un BaseConstructor:

// no error 
class Implementation extends MixFeature(Base as BaseConstructor) { 
    method() { 
    } 
} 

maintenant votre code compile. Mais notez que, puisqu'il n'y a aucun moyen de préciser que BaseConstructor représente un abstrait constructeur, la classe retournée sera interprétée comme concrète que vous le vouliez ou non, en dépit du fait que Mixed est déclarée comme abstract:

// also no error; may be surprising 
new (MixFeature(Base as BaseConstructor)); 

Pour l'instant, vous devrez juste faire attention si vous voulez utiliser des mixins avec des classes abstraites. Bonne chance!