-
Notifications
You must be signed in to change notification settings - Fork 12.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Entries cannot be reduced to an interface due to any
being assigned to never
#33651
Comments
This is a consequence of #30769 combined with #31838: the former mandates that Perhaps the cleanest way to resolve this without using casts is to introduce a generic parameter. const result: Thing = list.reduce(<K extends keyof Thing>(obj: Thing, [key, value]: [K, any]) => {
obj[key] = value;
return obj;
}, { foo: 0, bar: ''}); The exploits the fact that the effects of #30769 do not apply to generic indexed access types. |
First of all, thanks @jack-williams for the incredibly fast response ⚡️ I'm glad you've shown me a way to get around this without having to cast. I got curious and wanted to understand why this workaround exists, which caused me to start going down a rabbit hole of GitHub comments starting with yours back in April. Does the gist of this loophole come down to the fact that if an index is generic then TS currently can't resolve where it lands on an interface, meaning the type of that key's associated value can't be determined so it defaults to |
You are correct in saying that TS is unable to determine precisely where it lands, but it's not so permissive to default to obj[key] = true; Roughly, in the original example (which is concrete) TS knows all the types and can 'simplify' the indexed access for writing:
In the modified example (which is generic), TS doesn't precisely know all the types and defers any kind of approximation of the property type, so we have something like It's worthing highlighting that |
Got it, that makes sense and like you said #31838 is where Thanks again for the detailed explanation and workaround 👍🏼 Closing the issue now as it's expected behaviour. |
TypeScript Version: 3.7.0-dev.20190928
Search Terms:
Code
Ever since my team has updated to v3.6.3, the introduction of
never
has been causing us headaches whenever we try to reduce an array into a single typed object. The following example illustrates the issue we're faced with.My best guess is that this behaviour is due to recent changes in TS 3.5 to fix unsound writes to indexed access types. While understandable, I'm having some difficulty trying to reason about how we might achieve the behaviour demonstrated above without type aliasing
obj as any
or something similar? My gut tells me this should be achievable without breaking out of the type system (i.e. aliasing), which leads me to believe this could potentially be a bug.Expected behavior:
value
of typeany
is allowed to be set as a property ofThing
.Actual behavior:
The following compile-time error is thrown.
Playground Link:
https://www.typescriptlang.org/play/?target=99#code/JYOwLgpgTgZghgYwgAgCoAtQHNkG8BQyRyMA9qQFzIgCuAtgEbQA0hxDcUVAzmFNqwC++fAlIheyADbBeVAIJQocAJ4AeANoBrCCtIw0mEFmbI4IFQF0AfMgC8yDRoDkZUs9MBGS6ZccoHsjOHABezpaWANwiYhJgyFAQ3DRSYFQY2PbSsmAAdIkAJjRIABQlpAwAVulGJo46KqYAbnBSNBCWAJT2tgTEyBWV2rqWWS1tENH9iWA0UCADVdGCprgk5FQADKb+VM7Ogp2RQA
Related Issues:
N/A
The text was updated successfully, but these errors were encountered: