Определить тип возвращаемого метода в соответствии с классом, полученным в качестве параметра в машинописи - PullRequest
0 голосов
/ 25 апреля 2020

Возможно ли принудительное возвращение типа функции в соответствии с атрибутом stati c класса, полученного параметром?

В приведенном ниже коде я ожидаю, что переменная foo будет иметь тип Дата, равная атрибуту 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 Ответ

1 голос
/ 25 апреля 2020

Сначала вы можете создать тип для запроса класса с определением returnType (свойство stati c):

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. Может быть, вы хотите использовать это для других методов / stati c, однако я надеюсь, что это ответит на ваш вопрос.

Полный код: 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, {});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...