Amestecă într-o clasă de bază abstractă în Typescript
Aș dori să amestec câteva metode într-o clasă abstractă de bază, pentru a crea o nouă clasă abstractă.
Luați următorul exemplu:
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();
}
}
Acest lucru funcționează bine, dar scopul este să luăm implementările interfeței Feature și să le mutăm într-un mixin astfel încât să poată fi reutilizate de alte implementări ale clasei Base.
Am ajuns la următoarele, dar nu se compilează în Typescript 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() {
}
}
Dar Typescript nu aprobă, spunând:
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.
Este posibil să facem să funcționeze acest lucru sau este o limitare a Typescript că bazele abstracte nu pot fi extinse folosind mixinuri?
Răspuns #1
În prezent nu există nicio modalitate de a descrie tipul unui constructor de clasă abstractă în TypeScript. Problema GitHub Microsoft/TypeScript#5843 urmărește acest aspect. Poți să te uiți acolo pentru idei. O sugestie este că poți suprima eroarea pur și simplu afirmând că Base este un BaseConstructor:
// no error
class Implementation extends MixFeature(Base as BaseConstructor) {
method() {
}
}
Acum codul tău se compilează. Dar reține că, deoarece nu există nicio modalitate de a specifica că BaseConstructor reprezintă un constructor abstract, clasa returnată va fi interpretată ca fiind concretă indiferent dacă vrei sau nu, în ciuda faptului că Mixed este declarată ca abstract:
// also no error; may be surprising
new (MixFeature(Base as BaseConstructor));
Așadar, deocamdată va trebui să fii atent dacă vrei să folosești mixins cu clase abstracte. Mult noroc!
