I have the following definition for a curried function in TypeScript:
interface Curried2<A, B, Z> {
(_0: A): (_0: B) => Z;
(_0: A, _1: B): Z;
}
I have the following function that should accept a function (curried or not):
function apply<T, U>(f: (_0: T) => U, x: T): U {
return f(x);
}
Now, given
let curried: Curried2<number, boolean, string> = ...
the following works (as expected):
apply<number, (_0: boolean) => string>(curried, 4);
But TypeScript cannot infer the type on its own:
apply(curried, 4);
(Even though there is only one overload for ()
which takes a single value.) It complains:
Argument of type 'Curried2<number, boolean, string>' is not assignable to parameter of type '(_0: number) => string' ...It has correctly inferred
T
, but inferred U
to be string
. Why is this? What can I do to make type inference work for me in this case (as explicitly specifying T
and U
is too verbose for my taste)?
Thanks in advance!
I could try this approach:
type Curried<T1, T2, T3> = (x: T1) => (y: T2) => T3;
function apply<T, U>(f: (value: T) => U, x: T): U {
return f(x);
}
//simple demo
var someFunc: Curried<string, number, [string, number]> = x => y => [x, y];
var curriedSomeFunc = apply(someFunc, "string here");
var result1 = curriedSomeFunc(0); //will be ["string here", 0]
var result2 = curriedSomeFunc(1); //will be ["string here", 1]
Another try. The syntax is correct but no safety if you pass not a correct function for currying:
interface Curried<T1, T2, T3> {
(x: T1, y: T2): T3;
(x: T1): (y: T2) => T3
}
let f1 = <Curried<string, number, [string, number]>>
((x: string, y: number) => [x, 1]);
let f2 = <Curried<string, number, [string, number]>>
((x: string) => (y: number) => [x, y]);
function apply<T, V>(f: (x: T) => V, x: T): V {
return f(x);
}
let curriedF1 = apply(f1, "42"); //Won't work (no function to curry) but type inference is OK
let curriedF2 = apply(f2, "11"); //Will work and type inference is also OK
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments