I was not able to find an answer to the question why function thisDoesNotWork
causes an error. In contrast, function thisWorks
transpiles the line anyArgs.whatever();
without complaining, and I would expect this to work in the other function, too.
function thisWorks(anyArgs: any): any {
console.log(anyArgs);
anyArgs.whatever(); // NO ERROR
return anyArgs;
}
function thisDoesNotWork<T extends any>(anyArgs: T): T {
console.log(anyArgs);
anyArgs.whatever(); // ERROR: Property 'whatever' does not exist on type 'T'.
return anyArgs;
}
Since T
extends type any
, T
should be some sort of any
, too, so why does the line anyArgs.whatever();
cause an error here?
<T extends any>(anyArgs:T)
is not the same as (anyArgs:any)
. Generics add constrains to the type of values that are passed-in or returned from a method/function. So the generic <T extends any>(anyArgs:T)
parameter tells the compiler that yes - anything can be passed in, however because it does not know what the type of T
actually is ahead of time, it will not permit access or manipulation of the anyArgs
value.
Hence, <T extends any>(anyArgs:T)
is actually the same as <T>(anyArgs:T)
rather than being same as (anyArgs:any)
.
As mentioned by @jcalz, this behaviour was only added to TypeScript in version 3.9 and previous versions did in fact regard extends any
to be the same as any
. Link to this change here.