Peter Perot
Peter Perot

Reputation: 1003

Generic type parameter extending type "any" is not of type "any" anymore

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?

Upvotes: 0

Views: 527

Answers (1)

Ovidijus Parsiunas
Ovidijus Parsiunas

Reputation: 2732

<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.

Upvotes: 2

Related Questions