我有一个类A
,它具有函数f
(可能被子类覆盖)。
我想定义一个函数g
,以便g(cls, ...args)
仅在cls
是A
的子类并且args
与类型匹配时起作用cls.f
的签名。有办法吗?
编辑:我已经对上面的内容进行了更改,以反映以下事实:g
的第一个参数实际上是A
子类的 constructor ,而不是实例。
答案 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
是构造函数类型还是实例类型。