Repository navigation
Intersection on indexing a conditional type objectย #55804
Copy link
Copy link
Closed
Labels
Design LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixed
Description
๐ Search Terms
"indexing a conditional type object", "type mismatch indexing a conditional type object ts"
๐ Version & Regression Information
- This exists on 5.1.6 and latest (5.2.2)
โฏ Playground Link
๐ป Code
export const KEYS = ['cat', 'dog', 'fox', 'orca', 'ox'] as const
export const KEYS_TYPE_MAPPING = {
cat: 'options',
dog: 'options',
fox: 'options',
orca: 'range',
ox: 'range',
} as const
export type KeyValue = {
options: string[]
range: { min?: number; max?: number }
}
export type Items = {
[K in (typeof KEYS)[number]]?: KeyValue[(typeof KEYS_TYPE_MAPPING)[K]]
}
let animals: Items = {cat: ["x", "y", "x"]}
for (let key of KEYS) {
// union of possible value types in 'KeyValue'
let x = animals[key]
// ERROR: becomes an intersection when trying to set the value
animals[key] = x
}๐ Actual behavior
After creating a object type where each key has a mapped value type, an intersection of said types is created which causes object[key] to not be the same type as object[key] when setting a value at an index of the object.
It should not be an intersection type since the value types never overlap.
๐ Expected behavior
I expected the type of 'x' (when setting it as the value of object[key]) to be the same type as 'object[key]'. Since they both reference the same index in the same object. Also I would expect the type of 'x' and 'object[key]' to be a union of the value types since they do not overlap.
Additional information about the issue
No response
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Design LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixed
Activity
fatcerberus commentedon Sep 20, 2023
See #55756 (comment) and #30769. When
keyis union-typed, as it is here, the compiler doesnโt understand thatkeyrefers to the same property in both places. The intersection type arises because thatโs the only type thatโs known to be valid for any possiblekey.MaximilianFullStack commentedon Sep 20, 2023
Interesting, I assume the most optimal work around would be to explicitly type each key value as the union then? Unless there's something else that I'm not aware of.
Andarist commentedon Sep 21, 2023
There might be a way to write this in terms of correlated unions created out of mapped types: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-4-6.html#indexed-access-inference-improvements