打字稿,从接口中提取多个呼叫签名

时间:2020-01-29 14:13:10

标签: typescript

给出以下内容:

interface Foo {
  attr: string;
  (a: string): number;
  (a: number): number;
}

如何创建仅选择函数重载的类型,这意味着:

interface Bar {
  (a: string): number;
  (a: number): number;
}

当有just one call signature时我找到了解决方案,我的情况是有多个呼叫签名。

谢谢

1 个答案:

答案 0 :(得分:3)

没有完美的方法可以做到这一点。不支持仅删除属性,并且提取函数签名的版本具有局限性。我们可以获得具有多个重载功能的版本:

interface Foo {
  attr: string;
  (a: string): number;
  (a: number): number;
}

type JustSignatures<T> =
  T extends { (...args: infer A1): infer R1; (...args: infer A2): infer R2; (...args: infer A3): infer R3; (...args: infer A4): infer R4 } ?
  {
    (...args: A1): R1; (...args: A2): R2; (...args: A3): R3; (...args: A4): R4
  } :
  T extends { (...args: infer A1): infer R1; (...args: infer A2): infer R2; (...args: infer A3): infer R3 } ?
  {
    (...args: A1): R1; (...args: A2): R2; (...args: A3): R3
  } :
  T extends { (...args: infer A1): infer R1; (...args: infer A2): infer R2 } ?
  {
    (...args: A1): R1; (...args: A2): R2
  } :
  T extends { (...args: infer A1): infer R1; } ?
  {
    (...args: A1): R1;
  } :
  never;


type FooSignatures = JustSignatures<Foo>
// type FooSignatures = {
//     (a: string): number;
//     (a: number): number;
// }

Playground Link

这仍然具有不能用于具有泛型类型参数的函数的局限性。另外,我似乎还记得编译器中的一个错误,该错误会导致上述方法在某些极端情况下出现问题,但这在大多数情况下应该可以解决。