首页 > 解决方案 > 根据在打字稿中作为参数接收的类定义方法返回类型

问题描述

是否可以根据参数接收到的类的静态属性来强制函数的返回类型?

在下面的代码中,我希望变量 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, {});

请参见下图以更好地说明:

vscode 类型

另一张图片来说明:

在此处输入图像描述

标签: typescripttypes

解决方案


首先,您可以创建一个类型以请求具有已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()并期望returnTypeT. 这是不可能的,因为构造函数返回一个类 T 的实例。也许你喜欢将它用于其他目的/静态方法,但是我希望这能回答你的问题。

完整代码是: 游乐场链接

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, {});

推荐阅读