是否可以根据参数接收到的类的静态属性来强制函数的返回类型?
在下面的代码中,我希望变量foo为Date类型,等于作为参数接收的类的returnType
属性,但是我不知道该如何完成,或者有可能。
function register<T extends { new(...n: any[]): {} }>(constructor: T, ...args: ConstructorParameters<T>) {
// the error \\
return <constructor.returnType><unknown>new constructor(...args);
}
class Clazz {
static returnType: Date
constructor(p1: string, p2: number, p3: object) { }
}
let foo = register(Clazz, "", 1, {});
请参见下图以更好地说明:
另一幅图片来说明:
答案 0 :(得分:1)
首先,您可以创建一个类型以请求定义了returnType
(静态属性)的类:
type ClassWithReturnType = { new(...args: any[]): any; returnType: any; };
然后您就可以推断出returnType
,如下所示:
type ClassReturnType<T extends ClassWithReturnType> = T['returnType'] extends infer R ? R : never;
此时,您只需要将函数声明更改为:
function register<T extends ClassWithReturnType>(constructor: T, ...args: ConstructorParameters<T>): ClassReturnType<T> {
return (new constructor(...args));
}
对我来说,奇怪的是您正在呼叫new constructor()
,并且期望returnType
与T
不同。这是不可能的,因为构造函数返回类T的实例。也许您想将其用于其他目的/静态方法,但是我希望这能回答您的问题。
完整代码为: Playground Link
type ClassWithReturnType = { new(...args: any[]): any; returnType: any; };
type ClassReturnType<T extends ClassWithReturnType> = T['returnType'] extends infer R ? R : never;
function register<T extends ClassWithReturnType>(constructor: T, ...args: ConstructorParameters<T>): ClassReturnType<T> {
return (new constructor(...args));
}
class Clazz {
static returnType: Date;
constructor(p1: string, p2: number, p3: object) { }
}
let foo = register(Clazz, "", 1, {});