В моем functions.ts я определяю 2 функции, обе принимают объект api и возвращают функцию с разными типами аргументов, номерами аргументов и типами возвращаемых значений.
export function f1 (api: Api) {
return function (a: number): number[] {/* not important */}
};
export function f2 (api: Api) {
return function (a: string, b: string): boolean {/* not important */}
};
Теперь, имея глобальный объект api: Api, я хочу определить объект, который имеет поля f1 и f2, а значение, связанное с каждым полем, является внутренней функцией внутри двух вышеуказанных функций.
А именно, вручную я бы сделал:
const api: Api = ...;
const myObject = {
f1: f1(api),
f2: f2(api),
}
И это работает супер хорошо.
Но следующий шаг: я хочу сделать это динамично, т.е. не набирая вручную f1 и f2.
Вот мой старт:
import * as functions from './functions';
const api: Api = ...;
const myObject = Object.keys(functions).reduce((accumulator, functionName) => {
accumulator[functionName] = functions[functionName](api);
}, {} as ???);
Код работает, а типизация нет. Не знаю, что поставить вместо ???. {[index: keyof typeof functions]: (...args: any[]) => any} сработает, но я теряю много информации о типах.
Я пытался смотреть на ТС Parameters<T>, ReturnType<T> и уверен, что с infer можно что-то сделать, но не могу понять.






The code works, but the typings don't. I'm not sure what to put instead of ???.
Вот подход, который работает. Он создает новый тип, который сопоставляет каждое имя функции с типом возвращаемого значения.
type ReturnTypes<T> = {
[K in keyof T]: T[K] extends (...args: any) => any
? ReturnType<T[K]>
: never;
};
const myObject = Object
.keys(functions)
.reduce(
(accumulator, functionName) => {
accumulator[functionName] = functions[functionName](api);
return accumulator;
},
{} as ReturnTypes<typeof functions>
);
const result1: number[] = myObject.f1(10);
const result2: boolean = myObject.f2('foo', 'bar');
Вот он в Площадка TypeScript.
Исправлена ссылка на игровую площадку.
Хороший! Не могли бы вы поправить ссылку на игровую площадку, я посмотрю