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']);