Home > Software engineering >  TS infer parameters for each function member of an array
TS infer parameters for each function member of an array

Time:06-20

I'm trying to create a function utility where I can pass in an array as the argument to the function, where each member is an array with the following structure:

[ function, functionParams ]

Basically this helper adds some missing information to the function parameters that are common to every function; one example of this is a token value (these functions make HTTP calls); so, in reality, a member of the array value provided to this function looks like this:

[ Function, Omit<FunctionParams, CommonValues>]

The way I use this function is by providing an array to this helper function, and it calls everything in "parallel" (using Redux-Saga all).

I've tried so many approaches without successfully accomplish this; my best approach so far looks like this:

interface MyTypeFunction<T extends object = {}> {
 ( params: T & CommonProps ): any
}

function utilityHelper <T extends object> (
  param: [ MyTypeFunction<T>, T ][],
) {
 ...
}

The problem is that since the type argument (T) is defined for the whole function, when I call it with functions having a different parameter signature, TS will error because it is expecting all of them to have the same signature, most likely, the signature of the first element of the array (although sometimes it looks like TS in making an intersection of the parameters of each member, so yeah I'm not quite sure what's really happening). This is an example of it being used:

const functionA: MyTypeFunction<{ name: string}> = param => {};
const functionB: MyTypeFunction<{ id: number }> = param => {};

utilityHelper( [
  [ functionA, { name: 'Name' } ],
  [ functionB, { id: 358 } ],
] );

this will error for functionB saying something along the lines of {id: number} is not assignable to type {name: string}.

Is what I'm trying to do actually accomplishable?

CodePudding user response:

You probably want something like this:

function utilityHelper <T extends any[]> (
  param: [...{[K in keyof T]: [MyTypeFunction<T[K]>, T[K]]}],
) {}

This will enforce that you can only provide tuples where the second element is of the type of the argument of the provided function.

Playground

  • Related