(source, target, reportErrors, intersectionState, recursionFlags)
| 65470 | // equal and infinitely expanding. Fourth, if we have reached a depth of 100 nested comparisons, assume we have runaway recursion |
| 65471 | // and issue an error. Otherwise, actually compare the structure of the two types. |
| 65472 | function recursiveTypeRelatedTo(source, target, reportErrors, intersectionState, recursionFlags) { |
| 65473 | if (overflow) { |
| 65474 | return 0 /* Ternary.False */; |
| 65475 | } |
| 65476 | var keyIntersectionState = intersectionState | (inPropertyCheck ? 8 /* IntersectionState.InPropertyCheck */ : 0); |
| 65477 | var id = getRelationKey(source, target, keyIntersectionState, relation, /*ingnoreConstraints*/ false); |
| 65478 | var entry = relation.get(id); |
| 65479 | if (entry !== undefined) { |
| 65480 | if (reportErrors && entry & 2 /* RelationComparisonResult.Failed */ && !(entry & 4 /* RelationComparisonResult.Reported */)) { |
| 65481 | // We are elaborating errors and the cached result is an unreported failure. The result will be reported |
| 65482 | // as a failure, and should be updated as a reported failure by the bottom of this function. |
| 65483 | } |
| 65484 | else { |
| 65485 | if (outofbandVarianceMarkerHandler) { |
| 65486 | // We're in the middle of variance checking - integrate any unmeasurable/unreliable flags from this cached component |
| 65487 | var saved = entry & 24 /* RelationComparisonResult.ReportsMask */; |
| 65488 | if (saved & 8 /* RelationComparisonResult.ReportsUnmeasurable */) { |
| 65489 | instantiateType(source, makeFunctionTypeMapper(reportUnmeasurableMarkers)); |
| 65490 | } |
| 65491 | if (saved & 16 /* RelationComparisonResult.ReportsUnreliable */) { |
| 65492 | instantiateType(source, makeFunctionTypeMapper(reportUnreliableMarkers)); |
| 65493 | } |
| 65494 | } |
| 65495 | return entry & 1 /* RelationComparisonResult.Succeeded */ ? -1 /* Ternary.True */ : 0 /* Ternary.False */; |
| 65496 | } |
| 65497 | } |
| 65498 | if (!maybeKeys) { |
| 65499 | maybeKeys = []; |
| 65500 | sourceStack = []; |
| 65501 | targetStack = []; |
| 65502 | } |
| 65503 | else { |
| 65504 | // A key that starts with "*" is an indication that we have type references that reference constrained |
| 65505 | // type parameters. For such keys we also check against the key we would have gotten if all type parameters |
| 65506 | // were unconstrained. |
| 65507 | var broadestEquivalentId = id.startsWith("*") ? getRelationKey(source, target, keyIntersectionState, relation, /*ignoreConstraints*/ true) : undefined; |
| 65508 | for (var i = 0; i < maybeCount; i++) { |
| 65509 | // If source and target are already being compared, consider them related with assumptions |
| 65510 | if (id === maybeKeys[i] || broadestEquivalentId && broadestEquivalentId === maybeKeys[i]) { |
| 65511 | return 3 /* Ternary.Maybe */; |
| 65512 | } |
| 65513 | } |
| 65514 | if (sourceDepth === 100 || targetDepth === 100) { |
| 65515 | overflow = true; |
| 65516 | return 0 /* Ternary.False */; |
| 65517 | } |
| 65518 | } |
| 65519 | var maybeStart = maybeCount; |
| 65520 | maybeKeys[maybeCount] = id; |
| 65521 | maybeCount++; |
| 65522 | var saveExpandingFlags = expandingFlags; |
| 65523 | if (recursionFlags & 1 /* RecursionFlags.Source */) { |
| 65524 | sourceStack[sourceDepth] = source; |
| 65525 | sourceDepth++; |
| 65526 | if (!(expandingFlags & 1 /* ExpandingFlags.Source */) && isDeeplyNestedType(source, sourceStack, sourceDepth)) |
| 65527 | expandingFlags |= 1 /* ExpandingFlags.Source */; |
| 65528 | } |
| 65529 | if (recursionFlags & 2 /* RecursionFlags.Target */) { |
no test coverage detected
searching dependent graphs…