Distribute indexes of indexed access types first #27243
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Fixes #27224
This change is a small addition (plus a bunch of comments to illustrate the process) to
getSimplifiedIndexAccessType
. To begin, let me explain the original issue. The contextual typing issue reported boils down to this:This assignment worked in 3.0, and it should continue to do so. However the distribution change broke that, and in
master
(and 3.1) this assignment fails. Why? This is why: We'd see({ a: string } & { b: string })[K]
and distributeK
into the intersection, producing{ a: string }[K] & { b: string }[K]
. Then for each we would get its apparent type, which means its constraint. That produces{ a: string }["a" | "b"] & { b: string }["a" | "b"]
, which in turn becomes({ a: string }["a"] | { a: string }["b"]) & ({ b: string }["a"] | { b: string }["b"])
, which again becomes(string | unknown) & (unknown | string)
which is simplyunknown
(or for constraint calculation, no constraint - which is subtly different in that no constraint means it's not assignable).This changes this in two ways:
This changes how the algebra of the above example proceeds. Starting with
({ a: string } & { b: string })[K]
we do not simplify via distribution, then we get its constraint,({ a: string } & { b: string })["a" | "b"]
. This distributes into({ a: string } & { b: string })["a"] | ({ a: string } & { b: string })["b"]
which becomes({ a: string }["a"] & { b: string }["a"]) | ({ a: string }["b"] & { b: string }["b"])
which becomes(string & unknown) | (unknown & string)
which is now juststring
(asunknown
is a noop in an intersection likenever
is in a union), which is our desired type.