1

I'm trying to learn more about Generics function in TypeScript and I'm stuck on a compiler error.

I wrote two same functions but each one in a different way,

// FIRST FUNCTION
function genericFunctionOne<T>(first: T): T {
    return "Dummy return";
};

// SECOND FUNCTION
let genericFunctionOneBis: <T>(first: T) => T = first => "Dummy return";

the first one pass the compilator check but the second one does not.

ts/assign.ts(3,12): error TS2322: Type 'string' is not assignable to type 'T'.

Is that an expected behaviour ? I don't understand why one function passes the compilator check and not the other.

Here are the transpiled javascript:

// FIRST FUNCTION
function genericFunctionOne(first) {
    return "Dummy return";
};

// SECOND FUNCTION
var genericFunctionOneBis = function (first) { return "Dummy return"; };
Dipiks
  • 3,818
  • 2
  • 23
  • 39
  • I guess its the first function that will fail – Mitesh Pant Jan 25 '17 at 13:43
  • 2
    Actually the first one is what fails to compile, and the error is quite reasonable. I think the lambda version should give the same error, so this is probably a bug in TS. – Zoltán Tamási Jan 25 '17 at 13:43
  • it all fairness it should give an error in both cases. :-/ Also for me the first one fails and the arrow function succeeds. – toskv Jan 25 '17 at 13:43
  • You are returning a string for both, but the data type of the methods does not specify `string` so they should both fail, but only the first one does for me. – jhhoff02 Jan 25 '17 at 13:45
  • I understand they should both fail. But this is exactly why I'am asking this question, one fail and the other does not, event if the generated javascript behind is the same. I can invert the order of the function, and the arrow function will pass the compilator check anyway – Dipiks Jan 25 '17 at 13:52

1 Answers1

2

The reason is a subtle one, and there's another question that answers yours: What's the meaning of "=>" in TypeScript? (Fat Arrow)

Basically your first part:

let genericFunctionOneBis: <T>(first: T) => T

Only gives the information about the type of genericFunctionOneBis. Which in this case it is a function that accepts a parameter of type T, and returns something of same type T.

Second part, the assignment:

= first => "Dummy return";

That's your definition. Because you are not specifying type of first, it resolves T as being any, which means the definition matches the declared type of your variable.

Community
  • 1
  • 1
bug-a-lot
  • 2,446
  • 1
  • 22
  • 27
  • correct me if I'm wrong but didn't I specified the type of `first` as `T` ? – Dipiks Jan 25 '17 at 17:06
  • 1
    The actual type inferred for arrow function is `(first: any) => any` which is compatible with (first: T) => T when `any` is substituted in place of `T`. You get an error for that with --noImplicitAny compiler option. More interesting question is why there is no error when you assign (first: number) => "Dummy return" to genericFunctionOneBis even with --noImplicitAny – artem Jan 25 '17 at 18:27
  • As @artem said although you specified the type of first in the declaration, it is inferred from the assignment operation as any. – bug-a-lot Jan 26 '17 at 09:00