Trying to define a type for a function "factory", the issue arises when the number of arguments in the callback is unknown beforehand. Take a look at the following factory builder:
type Fn = (...args: any[]) => any
function apply<F extends Fn>(fn: F, ...applyArgs: Parameters<F>) {
return (...args: Parameters<F>) => fn(...(applyArgs || []), ...(args || []))
}
This pattern is quite common, as seen in this example factory:
function add(a: number, b: number) {
return a + b
}
// Error occurs here, Parameters expects 2 args but only got 1
const plus2 = apply(add, 2)
// Another error due to the parameter mismatch
plus2(2) // 4
The root issue is that the Parameters utility type requires all parameters to be used, not just some of them. The solution involves creating two types - ApplyArgs for initial parameters and RestArgs for remaining ones.
I attempted to define possible numbers of args manually, which did result in correct types for the params:
Type definitions...
While this method somewhat works:
function add(a: number, b: number) {
return a + b
}
// Now it works correctly
const plus2 = apply(add, 2)
// Works partially, but triggers TypeScript error
plus2(2) // 4
Although the rest params are technically undefined where applicable, TypeScript still expects the specified length for params. This clunky approach is not scalable with an infinite amount of potential params.
In conclusion, without the ability to recursively pass an index for inferring array indexes from a specific point, such as "
type Until<Id> = [infer Params[0:Id]
, I'm uncertain if this challenge is even achievable.
You can access the shared TypeScript playground here.