Skip to content
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

Intersection on indexing a conditional type object #55804

Closed
MaximilianFullStack opened this issue Sep 20, 2023 · 3 comments
Closed

Intersection on indexing a conditional type object #55804

MaximilianFullStack opened this issue Sep 20, 2023 · 3 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@MaximilianFullStack
Copy link

πŸ”Ž 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

https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBAYwgOwM7wNIFECaBlOAXjgG0ByBAQxjIBo4yATCAczoYDMIR2zore3MgF04lVIhToAsACg5oSLElpMuPAH0AKjgAKWDQFkAgrt0BJAHIBxInADecuImoAuBhDAwAllLpO4ZhZ3Pi9fNH9ZZy4QEM8fP1oA-koQqEpkFmBI5240jKzIgF8xCSRVOQVwaHgYAE8wYDgMYDqANUoAGwBXJuJHKLh48NR3dChvTJJhAPTM4Hd7OABbSYB+d2Ru5YAjYCgAbhXKEA24Ld39uCK5G-lZRRq4esa4cxhgZYl+gJIMOEmcAAFC9gBAOM11ABKEgXPZQYTCM4tdpdXokEENMEQ7D4bR6AwmMxWawwjCI26Ve6dYDwDLeZZdUZvD5fOz2KgwdwkABEIB59B5dQFcD5POEdzkXCgwJp8AA1q0hjjoQ4AgB6dVwbrIcLKuCQVCobw7GlwABuaKaoIkgLIKI6PWyATlcBAdnpjM6qBIirqM3uzk1cCwACVQwB5UPuPZIZbACQZAHID5QVDABAJZBwADuAAtgNmYFA6pMWM8IHB07UCxarQFPUzfa1RMQQJTZEA

πŸ’» 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

@fatcerberus
Copy link

See #55756 (comment) and #30769. When key is union-typed, as it is here, the compiler doesn’t understand that key refers 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 possible key.

@MaximilianFullStack
Copy link
Author

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
Copy link
Contributor

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

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Sep 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

4 participants