I have a function that stamps copies of classes. It takes a class and returns as many copies of classes as I specified. But the problem is not in the function but in its signature. To create new classes I need a function new
and to connect it I did extends { new(): T }
. I need it to return an array of classes with their type, but instead it returns (new () => typeof Rectangle)[]
and I can't figure out what the problem is. Here is the code.
class Rectangle {
w!: number;
h!: number;
}
class Circle {
radius!: number;
}
function stampFigures<T extends { new (): T } >(someClass: T, count: number): T[] {
let a = []
for (let i = 0; i < count; i )
a.push(new someClass());
return a;
}
let a: Rectangle[] = stampFigures(Rectangle, 10); //here i need Rectangle[] but i got (new () => typeof Rectangle)[]
let b: Circle[] = stampFigures(Circle, 20) //and here
console.log(a)
console.log(b)
CodePudding user response:
You need to infer an instance type of class:
class Rectangle {
w!: number;
h!: number;
}
class Circle {
radius!: number;
}
function stampFigures<
Klass extends { new(): any }
>(someClass: Klass, count: number) {
let a: InstanceType<Klass>[] = []
for (let i = 0; i < count; i )
a.push(new someClass());
return a;
}
let a = stampFigures(Rectangle, 10); // Rectangle[]
let b = stampFigures(Circle, 20) // Circle[]
console.log(a)
console.log(b)
YOu can also check my article
If you are interested in safest solution, you can create base class and extends your classes with tag
property. In other words, discriminate it.
class Shape {
tag: string = ''
}
class Rectangle extends Shape {
tag = 'Rectangle'
w!: number;
h!: number;
}
class Circle extends Shape {
tag = 'Circle'
radius!: number;
}
function stampFigures<
Klass extends typeof Shape,
Instance extends InstanceType<Klass>
>(someClass: Klass & (new () => Instance), count: number) {
let a = []
for (let i = 0; i < count; i )
a.push(new someClass());
return a;
}
let a = stampFigures(Rectangle, 10); // Rectangle[]
let b = stampFigures(Circle, 20) // Circle[]
console.log(a)
console.log(b)