Issue
how i can solve this issue with typescript ?
ex: When you have a class registers, and when you want creates a instances of all classes registered ?
export abstract class FooAbstract {
static registers: typeof FooAbstract[] = []; // a registers
static create<T extends FooAbstract>(constr: new ()=>T) {
return new constr();
}
}
export class A extends FooAbstract {
name:string;
}
FooAbstract.registers.push(A); // in my case i use decoration, but not matter !
// what should be the good way here ?
const test = FooAbstract.registers.map((cls)=> cls.create(cls))
Argument of type 'typeof FooAbstract' is not assignable to parameter of type 'new () => FooAbstract'.
Cannot assign an abstract constructor type to a non-abstract constructor type.ts(2345)
Solution
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
)
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.
Answered By - captain-yossarian
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.