Johannes Buchholz
Johannes Buchholz

Reputation: 2317

Typescript: use ReturnType of array of functions (edited)

I am trying to type the following function:

function foo(input, modifier, merge) {
    return merge(...modifier.map(m => m(input)));
}

The objective is to have the correct types for the parameters of the merge function.

Context:

How can this be done?


Edit: Alternative Question

Possible with objects (Record<K,V>):

// for Functions (here type Func)
type Func = () => any;

// a mapping of a string key to an function can be created
type FuncMap = Record<string, Func>;

// for this mapping you can create a mapping to the return types of each function
type ReturnTypeMap<T extends FuncMap> = { [K in keyof T]: ReturnType<T[K]> }

Is something like this also possible for arrays, based on the position instead of a object key?


This is my attempt at the typing the function, but i don't know how to use ReturnType in combination with arrays:

function foo<I, M extends Array<(input: I) => any>, O>(
    input: I,
    modifier: M,
    merge: (...args: ReturnType<M>) => O
    //               ^^^^^^^^^^^^^ this is not working, since relation to each item is missing
): O {
    return merge(...modifier.map(m => m(input)));
}

Upvotes: 3

Views: 2072

Answers (1)

Mike Jerred
Mike Jerred

Reputation: 10565

Do it like this I think:

type ExtractReturnTypes<T extends readonly ((i: any) => any)[]> = [
  ... {
    [K in keyof T]: T[K] extends ((i: any) => infer R) ? R : never
  }
];

function foo<I, M extends readonly ((i: I) => any)[], O>(
  input: I,
  modifiers: M,
  merge: (...args: ExtractReturnTypes<M>) => O
) {}

foo(
  1,
  [(i: number) => 5, (i: number) => 'b' as const] as const,
  // a has type: number
  // b has type: 'b'
  (a, b) => 'test'
);

Upvotes: 2

Related Questions