wenkang lin
wenkang lin

Reputation: 129

What's the difference of <T>(a: T) => U and <a: T> => U in TypeScript

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

Answers (1)

user8928802
user8928802

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

Related Questions