Home > Net >  Obtain parameter types of an array of functions in typescript
Obtain parameter types of an array of functions in typescript

Time:06-12

I'm trying to make kind of a composer functionality based on an array of functions. The idea is:

Assuming there exists two closure function func1 and func2 both with the same number of arguments that return the same function contract, let's say:
func1(arg1: {a: number}) => (a: number) => number
func2(arg1: {b: string}) => (a: number) => number

Now, the composer function is like:

  const composedFunction = compose({func1, func2});

The result of composedFunction is a function with an argument which let configure optionally the arguments to be passed to each function.

// ---------------------------- ∨ This is the value passed to the most inner function
const result = composedFunction(33, {func1: {a: 1}});
// --------------------------------- ∧ This is an object with the configuration of each function

Where the result variable will contain the composition of the result of each function. For clarity, lets say that

  const f1 = func1(...);
  const f2 = func2(...);
  // result will be f1(f2(33))

What have I achieved so far

type MyFunction = (value: any) => (a: number) => number;

export const compose = <T extends keyof any>(funcs: Record<T, MyFunction>) => {
  ...
  return (
    value: number,
    config?: Partial<{ [K in keyof typeof funcs]: Parameters<typeof funcs[T]>[0] }>,
  ) => {
    ...
  };
};

However, typescript says that for each function the configuration has a value of any.

const result = composedFunction(33, {func1: {a: 1}});
// --------------------------------- ∧ This configuration results in Partial<{ func1: any, func2: any}>

Any ideas on how to make the types of each function arguments appear on the configuration argument?

CodePudding user response:

Here is how I would fix it:

export const compose = <T extends Record<string, MyFunction>>(funcs: T) => {
  
  return (
    value: number,
    config?: Partial<{ [K in keyof T]: Parameters<T[K]>[0] }>,
  ) => {
    
  };
};

You only used T to infer the keys of the passed object. Any information about the functions passed is lost since you don't store it anywhere. When you use Parameters<typeof funcs[T]>[0], you will only get any as a result since the type of funcs is just Record<"func1" | "func2", MyFunction> which contains no information about the specfic functions you passed.

You should instead use T to infer the whole object with both the keys and the functions. When you use Parameters<T[K]>[0] now, T contains all the information about the functions.

Playground

  • Related