Typescript使用rest参数在子分段内生成新实例

Typescript使用rest参数在子分段内生成新实例,typescript,Typescript,我正在尝试创建一个父类,子类可以为其生成同类型子类的新实例 如果我指定了参数的数量,一切正常: abstract class AClass { protected sameTypeWithSingle ( x: any ): this { const self = this as this & { constructor: { new (x: any) } } return new self.constructor (x) }

我正在尝试创建一个父类,子类可以为其生成同类型子类的新实例

如果我指定了参数的数量,一切正常:

abstract class AClass {

  protected sameTypeWithSingle (
    x: any
  ): this {
    const self = this as this & {
      constructor: { new (x: any) }
    }
    return new self.constructor (x)
  }

  protected sameTypeWithDouble (
    a: any, b: any
  ): this {
    const self = this as this & {
      constructor: { new (a: any, b: any) }
    }
    return new self.constructor (a, b)
  }
}
但是,如果我尝试使用任意数量的参数(因此匹配任何子构造函数签名),它都不会起作用(在注释中是typescript错误:

abstract class AClass {

  protected sameTypeWith (
    ...args: any[]
  ): this {
    const self = this as this & {
      constructor: { new (...args: any[]) }
    }
    return new self.constructor (...args)
    // [ts] Cannot use 'new' with an expression whose type
    // lacks a call or construct signature.
  }
}
首先,我不明白为什么它会中断-它使用2个参数工作,但不使用任何参数? 此外,它们是实现我想要的东西的一种方式吗

提前谢谢


Seb

我同意这很奇怪。你可以看到
self.constructor
的类型是
函数&(new(…args:any[])=>any)
,这应该是可以更新的。但是编译器中发生了一些事情来防止这种情况,可能是
new(…args:any[])的一些特殊大小写
这有一个意外的副作用。如果我有时间,我可能会尝试跟踪这一点或提交一份文件,但我不能确定这一点

编辑:@MattMcCutchen评论道,看起来这是很久以前的事了。看起来他(很好!),所以我们可能会在TypeScript 3.2中看到这个问题消失


至于解决方法,您可以通过以下更改实现您想要的:

abstract class AClass {
  protected sameTypeWith(
    ...args: any[]
  ): this {
    const self = this as this & {
      constructor: { new(arg0?: any, ...args: any[]): any } // change here
    };
    return new self.constructor(...args); // works
  }
}

一个可选的第一个参数类型为
any
,后跟一个rest参数类型为
any[]
,相当于一个rest参数类型为
any[]
,因此您希望它们的行为相同,但显然不是。希望这会有所帮助。祝您好运!

看起来像这样。更新了指向问题的链接