You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Cannot be used to index type in 3.9 (worked in 3.8) #38740
// A *self-contained* demonstration of the problem follows...
// works in 3.8, fails in 3.9// Is this a bug in 3.9?// Nexus (nexusjs.org) depended on this functionalitytypeGet1<Aextendsany,Bextendsany,Cextends'filtering'|'ordering'>=AextendskeyofStuff
? BextendskeyofStuff[A]
? Stuff[A][B][C]// error here
: never
: never;interfaceStuff{// [k:string]: any // <-- Putting this here fixes Get1 in TS 3.9Blog: {// [k:string]: any // <-- Putting this here fixes Get1 in TS 3.9 posts: {filtering: 'a',ordering: 'b'}}}
Expected behavior:
TS 3.9 supports the same type logic as in 3.8 (see playground repro)
The immediate cause of this is #29571. Previously, a type parameter declared with extends any was treated as just any, which effectively turned off type checking. For example, you could change Stuff[A][B][C] to Stuff[A][42]['elephant'] in your example with no error!
We now treat extends any the same as having no constraint, meaning that things actually get checked. And, in your example A might not include 'Blog' and B might not include 'posts', so there is no guarantee that 'filtering' | 'ordering' is a valid key for Stuff[A][B]. You need to include another check to make it work:
typeGet1<Aextendsany,Bextendsany,Cextends'filtering'|'ordering'>=AextendskeyofStuff
? BextendskeyofStuff[A]
? CextendskeyofStuff[A][B]
? Stuff[A][B][C]// Ok
: never
: never
: never;
I also mistakenly thought that TS would statically analyze that Stuff only had filtering and ordering. I guess though the only way for that to happen would be having Stuff come through as a constrained generic.
There's probably an obvious reason TS must/does behave this way, but I don't see it.
Activity
ahejlsberg commentedon May 23, 2020
The immediate cause of this is #29571. Previously, a type parameter declared with
extends anywas treated as justany, which effectively turned off type checking. For example, you could changeStuff[A][B][C]toStuff[A][42]['elephant']in your example with no error!We now treat
extends anythe same as having no constraint, meaning that things actually get checked. And, in your exampleAmight not include'Blog'andBmight not include'posts', so there is no guarantee that'filtering' | 'ordering'is a valid key forStuff[A][B]. You need to include another check to make it work:jasonkuhrt commentedon May 23, 2020
Ahh thanks Anders Hejlsberg (@ahejlsberg) I thought I tried that 🤦.
I also mistakenly thought that TS would statically analyze that
Stuffonly hadfilteringandordering. I guess though the only way for that to happen would be havingStuffcome through as a constrained generic.There's probably an obvious reason TS must/does behave this way, but I don't see it.
Anyways, getting off-topic here.
Thanks again Anders Hejlsberg (@ahejlsberg)!