(sources, targets, variances, reportErrors, intersectionState)
| 65406 | return result; |
| 65407 | } |
| 65408 | function typeArgumentsRelatedTo(sources, targets, variances, reportErrors, intersectionState) { |
| 65409 | if (sources === void 0) { sources = ts.emptyArray; } |
| 65410 | if (targets === void 0) { targets = ts.emptyArray; } |
| 65411 | if (variances === void 0) { variances = ts.emptyArray; } |
| 65412 | if (sources.length !== targets.length && relation === identityRelation) { |
| 65413 | return 0 /* Ternary.False */; |
| 65414 | } |
| 65415 | var length = sources.length <= targets.length ? sources.length : targets.length; |
| 65416 | var result = -1 /* Ternary.True */; |
| 65417 | for (var i = 0; i < length; i++) { |
| 65418 | // When variance information isn't available we default to covariance. This happens |
| 65419 | // in the process of computing variance information for recursive types and when |
| 65420 | // comparing 'this' type arguments. |
| 65421 | var varianceFlags = i < variances.length ? variances[i] : 1 /* VarianceFlags.Covariant */; |
| 65422 | var variance = varianceFlags & 7 /* VarianceFlags.VarianceMask */; |
| 65423 | // We ignore arguments for independent type parameters (because they're never witnessed). |
| 65424 | if (variance !== 4 /* VarianceFlags.Independent */) { |
| 65425 | var s = sources[i]; |
| 65426 | var t = targets[i]; |
| 65427 | var related = -1 /* Ternary.True */; |
| 65428 | if (varianceFlags & 8 /* VarianceFlags.Unmeasurable */) { |
| 65429 | // Even an `Unmeasurable` variance works out without a structural check if the source and target are _identical_. |
| 65430 | // We can't simply assume invariance, because `Unmeasurable` marks nonlinear relations, for example, a relation tained by |
| 65431 | // the `-?` modifier in a mapped type (where, no matter how the inputs are related, the outputs still might not be) |
| 65432 | related = relation === identityRelation ? isRelatedTo(s, t, 3 /* RecursionFlags.Both */, /*reportErrors*/ false) : compareTypesIdentical(s, t); |
| 65433 | } |
| 65434 | else if (variance === 1 /* VarianceFlags.Covariant */) { |
| 65435 | related = isRelatedTo(s, t, 3 /* RecursionFlags.Both */, reportErrors, /*headMessage*/ undefined, intersectionState); |
| 65436 | } |
| 65437 | else if (variance === 2 /* VarianceFlags.Contravariant */) { |
| 65438 | related = isRelatedTo(t, s, 3 /* RecursionFlags.Both */, reportErrors, /*headMessage*/ undefined, intersectionState); |
| 65439 | } |
| 65440 | else if (variance === 3 /* VarianceFlags.Bivariant */) { |
| 65441 | // In the bivariant case we first compare contravariantly without reporting |
| 65442 | // errors. Then, if that doesn't succeed, we compare covariantly with error |
| 65443 | // reporting. Thus, error elaboration will be based on the the covariant check, |
| 65444 | // which is generally easier to reason about. |
| 65445 | related = isRelatedTo(t, s, 3 /* RecursionFlags.Both */, /*reportErrors*/ false); |
| 65446 | if (!related) { |
| 65447 | related = isRelatedTo(s, t, 3 /* RecursionFlags.Both */, reportErrors, /*headMessage*/ undefined, intersectionState); |
| 65448 | } |
| 65449 | } |
| 65450 | else { |
| 65451 | // In the invariant case we first compare covariantly, and only when that |
| 65452 | // succeeds do we proceed to compare contravariantly. Thus, error elaboration |
| 65453 | // will typically be based on the covariant check. |
| 65454 | related = isRelatedTo(s, t, 3 /* RecursionFlags.Both */, reportErrors, /*headMessage*/ undefined, intersectionState); |
| 65455 | if (related) { |
| 65456 | related &= isRelatedTo(t, s, 3 /* RecursionFlags.Both */, reportErrors, /*headMessage*/ undefined, intersectionState); |
| 65457 | } |
| 65458 | } |
| 65459 | if (!related) { |
| 65460 | return 0 /* Ternary.False */; |
| 65461 | } |
| 65462 | result &= related; |
| 65463 | } |
| 65464 | } |
| 65465 | return result; |
no test coverage detected
searching dependent graphs…