Reputation: 129
As stated in the title, if I have a function declared as below:
applyTo<T, U>(a: T): (a: T) => U
Call the function:
applyTo(1)(x => x + '2')
The TypeScript will show you an error:
TS2345:Argument of type '(b: number) => number' is not assignable to parameter of type 'number'.
Change the declare of applyTo
function as below code which will fix the error:
applyTo<T, U>(a: T): <T>(a: T) => U
I dont't know why? Can you tell me their differences?
Upvotes: 1
Views: 67
Reputation:
The missing implementation would make things more clear but the signature ...
applyTo<T, U>(a: T): (a: T) => U
says: "Give me some T and I'll give you back a function that takes some other T as parameter and returns some U." so you are supposed to pass as argument something of the same type T, like in:
applyTo(1)(2) // -> the result must be some U
Since in the first call a number were passed as argument, the compiler expected another number and not a function from (x: whatever) => x + '2'.
The second signature ...
applyTo<T, U>(a: T): <T>(a: T) => U
can be confusing just because naming, T in (a: T) => U is not necessarily the same type T in (a: T): ..., so would be better if each parameter and type parameter had a distinct name:
applyTo<T, U>(a: T): (b: T) => U
applyTo<T, U>(a: T): <S>(b: S) => U
Now the second signature say's: "Give me some T and I'll give back a function that takes some S as parameter and returns some U"
So depending on the implementation this would be valid:
applyTo(1) (x => x + '2') = ...
// ^^^^^^ ^^^^^^^^^^^^^^
// T is number S is function U is whatever;
// from whatever to
// string
Upvotes: 2