The issue is in this line (constr: new () => T) .
create static method expects a regular constructor, not an abstract constructr whereas you are trying to pass an abstract constructor to this method.
See here FooAbstract.registers.map((cls) => cls.create(cls)). cls.create expects new () => T but you are trying to use abstract new () => T.
You can add abstract flag/modifier to constr argument.
export abstract class FooAbstract {
static registers: typeof FooAbstract[] = [];
static create<T extends FooAbstract>(constr: abstract new () => T) { // add `abstract` modifier
return new constr();
}
}
const test = FooAbstract.registers.map((cls) => cls.create(cls))
But above approach, causes a new problem. You are not allowed to create an instance of abstract class, new constr() // <--- error is here.
UNSAFE APPROACH, MIGHT CAUSE AN ERROR IN RUNTIME. SEE @kaya3 COMMENTS
If you want to create an instance of some class, this class should not be an abstract.
Hence, we need to create an empty anonymous class which will extends our abstract class:
export abstract class FooAbstract {
static registers: typeof FooAbstract[] = [];
static create = <T extends FooAbstract>(constr: new () => T) => new constr()
}
const test = FooAbstract.registers.map((cls) =>
cls.create(class extends cls { }) // <--- anonymous class is just a wrapper
)
Playground
There is another one solution. You can just remove abstract keyword from FooAbstract class definition.
P.S. I'm not an OOP expert, so I can't say whether the answer I have provided meets OOP good practices or not. I have shown you just how to fix TS error
P.P.S if using abstract class or even OOP approach is not important for you, I can recommend another approach if you will provide more details to your question.