Distributed keyof over union leads to erroneous indexed access
See original GitHub issueBug Report
🕗 Version & Regression Information
This is the behavior in every version I tried
⏯ Playground Link
Playground link with relevant code
💻 Code
type KeyOf<T> = T extends unknown ? keyof T : never
type Wrong<T> = { [K in KeyOf<T>]: T[K] }
🙁 Actual behavior
It is accepted by the type checker, but it shouldn’t be allowed because T
could be a union of objects with unrelated properties. The computed type doesn’t even have any sense:
type test= Wrong<{ prop0: string } | { prop1: number; prop2: boolean } | { prop3: string[] }>
// { prop0: unknown; prop1: unknown; prop2: unknown; prop3: unknown; }
🙂 Expected behavior
K
shouldn’t be allowed to index type T
.
Issue Analytics
- State:
- Created a year ago
- Comments:11 (7 by maintainers)
Top Results From Across the Web
Mapped Types should distribute over union types · Issue #28339
This might be a bug or an intentional consequence of the original design, but mapped types do not distribute over union types.
Read more >Omitting a shared property from a union type of objects results ...
The easiest fix for this is to create a version of Omit that does distribute over unions by employing a distributive conditional type....
Read more >Unionize and Objectify: A Trick for Applying Conditional Types ...
We've used a mapped type [k in keyof T] and an index operation [keyof T] to transform the object type into a union...
Read more >Documentation - Advanced Types - TypeScript
Union types are useful for modeling situations when values can overlap in the types they can take on. What happens when we need...
Read more >An overview of computing with types • Tackling TypeScript
23.5.1 The index type query operator keyof; 23.5.2 The indexed access operator ... @ts-expect-error: Property 'propB' does not exist on type 'Union'. arg....
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Hi @RyanCavanaugh, @jfet97, @MartinJohns,
I created a PR that seem to fix this error.
The problem (paste again below) …
… seems to be that in
structuredTypeRelatedTo
(checker.ts
L19684-L19691),KeyOf<T>
is found to be related toT
, becausekeyof T
insideT extends unknown ? keyof T : never
returnsIndexType
.It seems to be a legit operation if e.g.
T extends **object** ? keyof T : never
instead ofT extends [some union]/ unknown ? keyof T : never
.So my working solution is to guard against return
IndexType
if the above conditions are met.I place the logic at
getTrueTypeFromConditionalType
.However, I am quite new to this and I am not quite sure:
getTrueTypeFromConditionalType
is the right place to place the logic; andIndexType
(I am returningUnknownType
)Please do give me a few pointers whether I am approaching this correctly.
Please do correct me if I am wrong!
Thank you for reviewing!
Hi there, I’d like to take a shot on this issue!