Разрешение TypeScript выводить тип из фабрики - PullRequest
0 голосов
/ 30 октября 2018

Возможно ли для TypeScript выводить тип возврата из статической функции. Например, если у меня есть статическая функция User.fromId(), она вернет объект User. Но я хочу передать его через другую функцию (назовите ее builder) - например:

builder(User.fromId, values);

, где builder определяется как:

function builder( construct: Function, values: any ) {
   var inst = construct();
   // set values
   return inst;
}

Как я могу заставить TypeScript "знать", что builder будет возвращать User без передачи User в качестве универсального? Возможно, это возможно, но проблема заключается в использовании Function в качестве типа для первого параметра? Если это так, может ли вывод быть сделан без универсального, который я знаю, я мог бы использовать, чтобы определить тип возвращаемого значения (но он чувствует себя избыточным).

Спасибо!

1 Ответ

0 голосов
/ 30 октября 2018

Если вы используете параметры универсального типа и соответствующую сигнатуру функции, Typescript выведет типы правильно

class User {
    static fromId(id: number): User{
        return new User()
    }
}

function builder<T>(construct: (id:number) => T, values: any) {
var inst = construct(values);
// set values
return inst;
}

let u = builder(User.fromId, 0); //User

Мы можем даже вывести тип параметра при необходимости

function builder<T, TId>(construct: (id:TId) => T, values: TId) {
    var inst = construct(values);
    // set values
    return inst;
}

let u = builder(User.fromId, 0);
let u2 = builder(User.fromId, '0'); // error

Если функция конструктора имеет больше параметров, мы можем даже вывести их при необходимости, используя кортежи в параметрах отдыха

class User {
    static fromId(id: number, name: string): User{
        return new User()
    }
}

function builder<T, TArgs extends any[]>(construct: (...a:TArgs) => T, ...values: TArgs) {
    var inst = construct(...values);
    // set values
    return inst;
}

let u = builder(User.fromId, 0, '');
let u2 = builder(User.fromId, '0'); // error
...