Как-то так, если по красоте:
type Returns<T extends readonly Function[]> = {
-readonly [K in keyof T]: T[K] extends (...args: any[]) => PromiseLike<infer R> ? R : never;
};
type Arguments<T extends readonly Function[]> = {
[K in keyof T]?: T[K] extends (args: infer R, ...a: any[]) => any ? R : never;
};
function fetchAll<T extends readonly Function[]>(functions: readonly [...T], data?: Arguments<T>): Promise<Returns<T>> {
return Promise.all(
functions.map((func, index) => func(data?.[index]))
) as Promise<Returns<T>>;
}
const x = fetchAll([
(a:66) => Promise.resolve(42),
(f:string) => Promise.resolve('hello'),
() => Promise.resolve(true),
], [66, '1ff']);
Если надо отельный массив, то придётся его руками const:
const arr = [
(a:66) => Promise.resolve(42),
(f:string) => Promise.resolve('hello'),
() => Promise.resolve(true),
] as const;
const x = fetchAll(arr, [66, '1ff']);