Skip to content

Commit

Permalink
Keep indexed access recursion depth check
Browse files Browse the repository at this point in the history
  • Loading branch information
ahejlsberg committed Oct 31, 2021
1 parent 52e10d3 commit 5f37d89
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20359,6 +20359,13 @@ namespace ts {
// though highly unlikely, for this test to be true in a situation where a chain of instantiations is not infinitely
// expanding. Effectively, we will generate a false positive when two types are structurally equal to at least maxDepth
// levels, but unequal at some level beyond that.
// In addition, this will also detect when an indexed access has been chained off of maxDepth more times (which is
// essentially the dual of the structural comparison), and likewise mark the type as deeply nested, potentially adding
// false positives for finite but deeply expanding indexed accesses (eg, for `Q[P1][P2][P3][P4][P5]`).
// It also detects when a recursive type reference has expanded maxDepth or more times, e.g. if the true branch of
// `type A<T> = null extends T ? [A<NonNullable<T>>] : [T]`
// has expanded into `[A<NonNullable<NonNullable<NonNullable<NonNullable<NonNullable<T>>>>>>]`. In such cases we need
// to terminate the expansion, and we do so here.
function isDeeplyNestedType(type: Type, stack: Type[], depth: number, maxDepth = 3): boolean {
if (depth >= maxDepth) {
const identity = getRecursionIdentity(type);
Expand Down Expand Up @@ -20410,6 +20417,13 @@ namespace ts {
if (type.flags & TypeFlags.TypeParameter) {
return type.symbol;
}
if (type.flags & TypeFlags.IndexedAccess) {
// Identity is the leftmost object type in a chain of indexed accesses, eg, in A[P][Q] it is A
do {
type = (type as IndexedAccessType).objectType;
} while (type.flags & TypeFlags.IndexedAccess);
return type;
}
if (type.flags & TypeFlags.Conditional) {
// The root object represents the origin of the conditional type
return (type as ConditionalType).root;
Expand Down

0 comments on commit 5f37d89

Please sign in to comment.