1
votes

I am new to typescript and I am trying to wrap my head around how generics work. I am wondering why the following code doesn't fly:

function identity<T>(arg: T): T {
    let num: number = 2;
    return num;
}

let output = identity<number>(1);

I get the error: Type 'number' is not assignable to type 'T'. If the input to the function is a number, does this not mean that the return type of number should work as well, since we are saying that T is of type number?

3
T is not going to necessarily be a number. You might have, for example identity<string>("hello") in which case return num would be wrong. You've put nothing to ensure that T is in any way related to number, so TS will fail compiling this as it cannot guarantee the compatibility. - VLAZ

3 Answers

0
votes

You have to treat T like any type in existence. Your function head says: I want an argument of type T and return something of type T.

Your code however always returns a number, which does not have to be T. In your example call it is, but you could call it with identity<string>("test") and expect a string to come back, but it would still be a number. Thus the confict.

0
votes

Let's have a look at the type signature of your identity function.

function identity<T>(arg: T)

What we are saying here is that this function acceps an argument of type T (which we are not specifying in advance, it could be anything), and it return a value of type T.

Given that there is no information whatsoever about T, the only the function can return a value of such type is to reuse the provided argument. In other words, there is exactly one and only one possible implementation of the identity function - the one that returns its argument.

function identity<T>(arg: T) { return arg }

The error message is telling you exactly this: Type 'number' is not assignable to type 'T', which is true because T is, well, generic :)

0
votes

Short story , you should correct your function like this:

function identity<T>(arg: T): T {
    let num: T = arg;
    return num;
}

let output = identity<number>(1)


console.log(output);