0

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?

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.