Fix recursive mapped type infinite recursion #21134
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 #17847
isGenericMappedType
indirectly callsgetResolvedBaseConstraint
, but is called indirectly from insidegetResolvedBaseConstraint
. This avoids the circularity check ingetResolvedBaseConstraint
, which causes an infinite recursion for certain malformed types.Interestingly, I found four approaches that fixed the bug:
if (isGenericMappedType(t)) { return emptyObjectType; }
)typeStack
toisGenericMappedType
and check it ingetConstraintOfTypeParameter
instead of callinghasNonCircularBaseConstraint
.isGenericMappedType
and its callees intogetResolvedBaseConstraint
(and checktypeStack
).isGenericMappedType
and its callees intogetResolvedBaseConstraint
, and merge into a single function (that checkstypeStack
).And @weswigham suggested a fifth,
typeStack
and usepush/popTypeResolution
instead.Previously, I decided on (2) because it avoids forking the code paths, but (5) reuses code even better.