如何推断 TypeScript 中重载构造函数的类型?

问题描述 投票:0回答:1

bindNew
错误地推断了构造函数类型,仅识别多个重载版本之一。

如何解决?

function bindNew<C extends { new(...args: A): T }, A extends any[], T>(
  klass: C & { new(...args: A): T }
): C & ((...args: A) => T) {
  return new Proxy(klass, {
    apply(target, _self, args) { return new (target as any)(...args) }
  }) as any
}

class AClass {
  constructor(a: number)
  constructor(a: number, b: number)
  constructor(a: number, b?: number) {}
}

const A = bindNew(AClass)
A(0) // => Error: expects 2 arguments
A(0, 0)

// This works, but requires explicit type declaration
// interface A extends AClass {}
// const A = bindNew(AClass) as typeof AClass & {
//   (a: number): A
//   (a: number, b: number): A
// }

游乐场

typescript
1个回答
0
投票

似乎不可能,TS推断出最后一个重载签名。但是你有一个非常简单的情况,你可以将构造函数参数作为元组的并集。我已将第二个签名更改为

a: string
,因此很明显该签名在第二个测试用例中处于活动状态:

游乐场

function bindNew<C extends { new(...args: A): T }, A extends any[], T>(
  klass: C & { new(...args: A): T }
): C & ((...args: A) => T) {
  return new Proxy(klass, {
    apply(target, _self, args) { return new (target as any)(...args) }
  }) as any
}

class AClass {
  constructor(...args: [a: number] | [a: string, b: number]){

  }
}

type t = ConstructorParameters<typeof AClass>

const A = bindNew(AClass)
A(0)
A('string', 0)
© www.soinside.com 2019 - 2024. All rights reserved.