Suppose I have a function partial()
, that takes a callable and arguments that have to be passed to it, and prefills the first argument of the callable.
How should I annotate its parameters for the type check to work, no matter which callable I pass to it.
function foo(a: string, b: number, c: string) {
console.log('foo', a, b, c)
}
function bar(a: string) {
console.log('bar', a)
}
function partial(callable, ...args) {
callable('identity', ...args)
}
If it helps, this is what I am currently trying, but doesn't quite work:
partial<T>(callable: (...args: [string, ...T[]]) => void, ...args: T[]) {
callable('partial a', ...args);
}
CodePudding user response:
You want to represent the rest of the arguments as a tuple type, so that the compiler keeps track of the number and order of the different argument types. It looks like this:
function partial<T extends any[]>(
callable: (...args: [string, ...T]) => void, ...args: T
) {
callable('identity', ...args)
}
So the type parameter T
is already an arraylike type. When you call partial()
:
partial(foo, 1, "okay") // "foo", "identity", 1, "okay"
// function partial<[number, string]>(callable:
// (args_0: string, args_1: number, args_2: string) => void,
// args_0: number, args_1: string): void
partial(bar); // "bar", "identity"
// function partial<[]>(callable: (args_0: string) => void): void
You can see that for foo
, T
gets inferred as [number, string]
, while for bar
, T
gets inferred as []
(the empty tuple).