I would like to make a funciton to return a class which extends a derived class of an abstract class in Typescript. I think Abstract Construct Signature should be the one I should use. However, Typescript prompts "Non-abstract class 'SayHelloDerived' does not implement all abstract members of 'Base'." Here is a simplified code.
// @errors: 18052
abstract class Base {
abstract getName(): string;
printName() {
console.log("a")
}
}
class Derived extends Base {
getName() {
return "";
}
}
function makeSayHelloDerived(DerivedBase: new () => Base) {
return class SayHelloDerived extends DerivedBase {
sayHello() {
console.log("hello!");
}
}
}
const Derived2 = makeSayHelloDerived(Derived);
const derived2 = new Derived2;
derived2.sayHello();
const Derived3 = makeSayHelloDerived(Base);
const derived3 = new Derived3;
derived3.sayHello();
The second error is expected, but the first one is not.
I expect Typescript can recognize parameter "DerivedBase" in function "makeSayHelloDerived" as a derived class of abstract "Base" class. It should not prompt any error, but it prompts now. I have googled around and search stackOverflow here about "Abstract Construct Signature," but no luck. Did I have anything wrong?
The easy solution would be to change the type of the parameter to new () => Derived
, but I suppose that's not what you want - you want to accept any non-abstract class that inherits from Base
.
I'm not certain how exactly this works, but I managed to do this by explicitly adding the concrete method signature to the type of the construct signature:
function makeSayHelloDerived(DerivedBase: new () => Base & { getName(): string }) {
return class SayHelloDerived extends DerivedBase {
sayHello() {
console.log("hello!");
}
}
}