Home > OS >  Combine two functions into one
Combine two functions into one

Time:12-19

The goal here is to create one function from 2 functions with argument combination. It could be easily done with JavaScript, but it's not easy with typescript.

One way to combine two functions is Proxy. Example:

const f1 = (a: number) => {
    return (a   1) * 2;
} 

const f2 = (b: string, c: string[]) => {
    c.push(b);
    return c;
}

const combiner = (f1: Function, f2: Function) => {
    return new Proxy(f1, {
        apply(target, thisArg, args) {
            const f1_args = args.slice(0, f1.length);
            const f2_args = args.splice(f1.length);
            f1(...f1_args);
            f2(...f2_args);
        }
    });
};

const f = combiner(f1, f2);

f(1, 'foo', ['bar']); // Typehints?

The question is could it be typed with typescript to typehint result of combiner function?

CodePudding user response:

Typing the parameters of the combined function is trivially achieved by using two generic types A1 and A2 which hold the parameter tuple types of the two functions.

const combiner = <
  A1 extends any[], 
  A2 extends any[]
>(f1: (...args: A1) => void, f2: (...args: A2) => void) => {
    return new Proxy(f1, {
        apply(target, thisArg, args) {
            const f1_args = args.slice(0, f1.length);
            const f2_args = args.splice(f1.length);
            f1(...f1_args as A1);
            f2(...f2_args as A2);
        }
    }) as unknown as (...args: [...A1, ...A2]) => void
};

We only need to assert that the returned type is a function which has the combined A1 and A2 tuples as its parameter type.

const f = combiner(f1, f2);
//    ^? const f: (a: number, b: string, c: string[]) => void

f(1, 'foo', ['bar']);

Playground

  • Related