Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't TypeScript enforce a generic parameter in callback?

Consider this TypeScript code, compiled with 2.6.1:

function foo<T> (bar: T, baz: (T) => void) {
    const test: T = bar;
    baz(test);
}

const string: string = "a";
foo(string, num => num.parseInt());

I would expect the compilation to fail, because the function foo is called with a string, but the passed callback function is using a method that is not available in string -- while the function signature indicates that type of argument in callback function should be the same as the type of the first parameter.

However, the code compiles and then fails in runtime.

What am I missing?

like image 523
sbichenko Avatar asked Feb 27 '26 08:02

sbichenko


1 Answers

Well, because T in baz: (T) => void is not a type name, it's a parameter name.

When you fix the syntax to mean what you want it to mean, you get the expected error:

function foo<T> (bar: T, baz: (t: T) => void) {
    const test: T = bar;
    baz(test);
}

const s: string = "a";
foo(s, num => num.parseInt()); 
// Property 'parseInt' does not exist on type 'string'.

Granted, it's really hard to spot errors like this one - I saw it only when I pasted your code into typescript playground and turned on --noImplicitAny. (T) immediately got highlighted with Parameter 'T' implicitly has an 'any' type. Even that error was puzzling for a moment - wait what - T is not a parameter, it's a type - ...!

like image 72
artem Avatar answered Mar 01 '26 16:03

artem