打字稿要求参数匹配第一个参数的类型签名

时间:2018-12-22 01:13:38

标签: typescript types

我有一个类A,它具有函数f(可能被子类覆盖)。

我想定义一个函数g,以便g(cls, ...args)仅在clsA的子类并且args与类型匹配时起作用cls.f的签名。有办法吗?

编辑:我已经对上面的内容进行了更改,以反映以下事实:g的第一个参数实际上是A子类的 constructor ,而不是实例。

1 个答案:

答案 0 :(得分:4)

当然,从TS 3.0开始,您可以使用tuples in rest/spread types来获取它:

declare class A {
  f(...args: any[]): any;
}
declare function g<T extends A>(val: T, ...args: Parameters<T['f']>): void;

declare class B extends A {
  f(x: string, y: number): boolean;
}
declare const b: B;
g(b, "hey", 123); // okay
g(b, 123, "hey"); // error

元组剩余/扩展推断隐藏在standard library中定义的Parameters类型的函数中,为:

type Parameters<T extends (...args: any[]) => any> = 
  T extends (...args: infer P) => any ? P : never;

这是您要找的吗?


编辑:如果val应该是构造函数,那么您可以这样做:

declare function g<T extends A>(
  val: new(...args:any[])=>T, 
  ...args: Parameters<T['f']>
): void;

declare class B extends A {
  f(x: string, y: number): boolean;
}
g(B, "hey", 123); // okay
g(B, 123, "hey"); // error

或者基本上是同一件事:

declare function g<T extends new (...args: any[]) => A>(
  val: T,
  ...args: Parameters<InstanceType<T>['f']>
): void;

取决于您希望T是构造函数类型还是实例类型。