TS2322:类型“(new () => typeof Rectangle)[]”不可分配给类型 'Rectangle[]'

TS2322: Type '(new () => typeof Rectangle)[]' is not assignable to type 'Rectangle[]'

我有一个功能可以标记 classes 的副本。它需要 class 和 returns 与我指定的 classes 一样多的副本。但问题不在于函数,而在于它的签名。要创建新的 classes,我需要一个函数 new 并连接它,我做了 extends { new(): T }。我需要它 return 一个 classes 及其类型的数组,但它 returns (new () => typeof Rectangle)[] 而我无法弄清楚问题是什么。这是代码。

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)

您需要推断 class 的 instance type

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)

Playground

你也可以查看我的article

如果您对最安全的解决方案感兴趣,可以创建基础 class 并使用 tag 属性 扩展您的 classes。换句话说,歧视它。

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)

Playground