I'm trying to create a generic method that can accept any amount of parametrs, while saving that input type for later. An example:
const wrappingFunction = <A extends any[]>(innerFunction: (...args: A) => void, defaultParams: A) => {
const applyFunction = (...args: A) => innerFunction(...args);
const defaultValue = applyFunction(...defaultParams);
return applyFunction;
};
In this example, I want to be able to call this method with a method that takes parameters and default values like this:
const f1 = wrappingFunction(
(a: string) => {
return;
},
["default"]
);
And also be able to call it with a parameter-less function and no default values like this:
const f2 = wrappingFunction(() => {
return;
});
The problem is with making f2
possible.
CodePudding user response:
Adding a generic type A
which represents the arguments of the function should solve this.
const wrappingFunction = <A extends any[]>(
innerFunction: (...args: A) => void,
...defaultParams: A extends [] ? [] : [A]
) => {
const applyFunction = (...args: A) => innerFunction(...args);
const defaultValue = applyFunction(...defaultParams as any);
return { applyFunction, defaultValue };
};
const f1 = wrappingFunction(
(a: string) => {
return;
},
["default"]
);
const f2 = wrappingFunction(() => {
return;
});
We can use a conditional type for defaultParams
and make it a rest parameter. But this requires us to use any
in the function implementation.
It would probably better to not use an array at all and just use the rest parameter.
const wrappingFunction = <A extends any[]>(
innerFunction: (...args: A) => void,
...defaultParams: A
) => {
const applyFunction = (...args: A) => innerFunction(...args);
const defaultValue = applyFunction(...defaultParams);
return { applyFunction, defaultValue };
};
const f1 = wrappingFunction(
(a: string) => {
return;
},
"default"
);
const f2 = wrappingFunction(() => {
return;
});