union-proof the 'generic mapped type' check #18036
Closed
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 #15756.
This incidentally also uncovered one other case (
Form
fromkeyofAndIndexedAccess
) where generic mapped types had been applied in an unsound way w.r.t. union keys. That simplified heuristic worked there for the basic case of non-union types, but without it inference ended up no longer strong enough there.That appears a piece of collateral damage here, though I'm under the impression the altered check here wasn't wrong about such reduction being unsound there.
To elaborate:
Reduction makes for
{[K in keyof T]: (v: T[K]) => Form<T[K]>}[K]
->(v: T[K]) => Form<T[K]>
. If one substitutes some unionA|B
forK
, that makes for(v: T[A|B]) => Form<T[A|B]>
, distinct from the (I believe) expected result here of((v: T[A]) => Form<T[A]>) | ((v: T[B]) => Form<T[B]>)
. That's why I believe this reduction here was technically unsound even though it would have held for the base case of non-unions.