Reputation: 956
I have an abstract class A, B and C both inherit A
Now I want to extend both B and C with the same methods, so basically I'd like B and C to inherit a class ExtendedA, but I don't want to change A, B and C
It could work with mixins however since A is abstract, the mixin function has no way to know that the abstract methods are actually implemented in B and C, so naturally it gives me an error:
abstract class A {
protected a = 1;
public abstract hello(): void;
}
class B extends A {
public hello() {
console.log('hello from B');
}
}
class C extends A {
public hello() {
console.log('hello from C');
}
}
type AConstructor = new(...args: any[]) => A;
function ExtendedA<T extends AConstructor>(Base: T) {
return class extends Base {
public doSomething() {
this.hello();
console.log('do something', this.a);
}
}
}
class ExtendedB extends ExtendedA(B) {
}
class ExtendedC extends ExtendedA(C) {
}
const d = new D();
const e = new E();
d.doSomething();
// hello from B
// do something 1
e.doSomething();
// hello from C
// do something 1
test.ts:22:12 - error TS2653: Non-abstract class expression does not implement inherited abstract member 'hello' from class 'A'.
am I not seeing something or is there no way to do it in typescript?
Upvotes: 1
Views: 533
Reputation: 3723
Your problem is that AConstructor
defines a type that extends A
, and ExtendedA
is extending that type, but no class is implementing A
(which is abstract) methods. Try using an interface instead:
interface AInterface {
hello();
}
type AConstructor = new (...args: any[]) => AInterface;
let ExtendedA = (Base: AConstructor): any => {
return class extends Base {
public doSomething() {
this.hello();
console.log("do something", this.a);
}
};
};
Note: protected property is not accesible from grandchildren, only for children.
Upvotes: 2