根据在打字稿中作为参数接收的类定义方法返回类型

时间:2020-04-24 23:23:37

标签: typescript types

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

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

另一幅图片来说明:

enter image description here

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(),并且期望returnTypeT不同。这是不可能的,因为构造函数返回类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, {});