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
Const indexed access issue β should attempt widening to a mapped typeΒ #51156
Anders Hejlsberg (@ahejlsberg) This issue seems nearly identical to #47368, but this time for const object types which are assignable to the mapped type.
typeArgMap={a: number,b: string};typeFunc<KextendskeyofArgMap>=(x: ArgMap[K])=>void;typeFuncs={[KinkeyofArgMap]: Func<K>};constfuncs={a: (x: number)=>{},b: (x: string)=>{},};functionf1<KextendskeyofArgMap>(key: K,arg: ArgMap[K]){funcs[key](arg);}functionf2<KextendskeyofArgMap>(key: K,arg: ArgMap[K]){constfunc=funcs[key];// Type Funcs[K]func(arg);}functionf3<KextendskeyofArgMap>(key: K,arg: ArgMap[K]){constfunc: Func<K>=funcs[key];// Error, Funcs[K] not assignable to Func<K>func(arg);}
π Actual behavior
Unexpected error in example above.
It's unexpected because throwing away type information makes this type check correctly, by widening with either const funcs: Funcs (all examples) or const func: Funcs[K] (in f2). So the compiler actually is able to confirm that indexed type is assignable to the mapped type, it just doesn't try without being explicitly prompted.
K can also be a union type, like "a" | "b". In this case your type Funcs[K] resolves to (x: number) => void | (x: string) => void. When trying to call a union like this, you must provide a value that's compatible with all possible argument types, because the compiler doesn't know whether it has a function accepting a string or a number - so the type you must provide must be both: string & number. But such a type can't be represented, so you end up with never.
Activity
MartinJohns commentedon Oct 12, 2022
This is working as intended.
Kcan also be a union type, like"a" | "b". In this case your typeFuncs[K]resolves to(x: number) => void | (x: string) => void. When trying to call a union like this, you must provide a value that's compatible with all possible argument types, because the compiler doesn't know whether it has a function accepting astringor anumber- so the type you must provide must be both:string & number. But such a type can't be represented, so you end up withnever.RyanCavanaugh commentedon Oct 12, 2022
The error is correct, though if you formulate your arguments to a specific pattern, a convenient soundness hole will be created for you. See #47109
typescript-bot commentedon Oct 15, 2022
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes.