Using Typescript 1.4, say I have a higher-order function with the signature:
interface F<A,B> {
(a: (...x:any[]) => A): (...x:any[]) => B
}
Function 'F' takes function 'a' which has a set of parameters 'x'. Function 'F' returns a new function which has exactly the same set of args as function 'a'.
I've been trying to find a way to express this in Typescript, but i'm coming up short. For example:
interface F<X extends Array<any>,A,B> {
(a: (...x:X) => A): (...x:X) => B
}
the compiler just complains with: error TS2370: A rest parameter must be of an array type.
Although that doesn't feel right anyway, even if it did compile. I guess i'd really need something like:
interface F<X extends Tuple,A,B> {
(a: (...x:X) => A): (...x:X) => B
}
Anyone know if this kind of thing is even possible with Typescript currently (1.4 at time of writing)? or any suggestions?
Example:
(NOTE: This is not my actual use-case, i'm only using logging here as a simple example - please don't focus on that aspect)
// a higher-order function that takes any function and
// returns a new function which takes the same args
// passing them to the original fn and logging the args along with the result
function f(a:(...x:any[]) => any): (...x:any[]) => void {
return (...x:any[]) => {
console.log('('+x.join(',')+') => ', a.apply(undefined, x));
}
}
function a(j:string, k:number): boolean {
return j === String(k);
}
var b = f(a);
b("1", 1);
b("a", 2);
console output:
(1,1) => true
(a,2) => false
So this works, but the derived function 'b' has the implied signature of:
(...x:any[]) => void
ideally i'd like it to have the same arguments as function 'a' ie:
(j: string, k: number) => void
I know I could explicitly define that, but it's very verbose and not at all ideal, kind of defeats the point of having the strong typing in the first place:
var b: (j:string, k:number) => void = f(a);