fix: Fix spreading abstract fragments into abstract selections widening the result type #102
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.
Resolves #100
Summary
This improves the type inference for two cases specifically.
When spreading a fragment of an interface (potentially itself) into an interface selection, the type wasn't narrowed even if we had the fragment available and were doing a submatch. This lead to poor type matches when a user wasn't specifying
__typename
above and below the spread although this isn't necessary, since we have all necessary type information.We can generically solve this by keeping the
PossibleType
narrow, specifically by skippinggetSelection
and usinggetPossibleTypeSelectionRec
directly.Specifically, when using an unmasked fragment document and repeating the above a similar issue would occur. In such a case the type checker would be forced to accept two unions of two types that aren't mergeable.
There isn't a great solution for this without refactoring a whole lot and making output types less readable, while hurting performance in the process.
There is however a simple solution.
We now always attach a
__typename?: PossibleType
optional property to possible type selections. This attaches a type to match against for the type checker to merge all possible types’ selections.While not the perfect solution, this shouldn't have any negative consequences.
never
when a branch is missing a typename providing a visual indicator that__typename
isn't selected in all cases__typename
is unlikely to be aliased (which we can also lint for), since it's a system field and unique in behaviourSet of changes
getSelection
and usegetPossibleTypeSelectionRec
directly, where possiblePossibleType
in nested fragment selections__typename?: PossibleType
property to possible type selections