* Compare two types and return * * Ternary.True if they are related with no assumptions, * * Ternary.Maybe if they are related with assumptions of other relationships, or * * Ternary.False if they are not related.
(originalSource, originalTarget, recursionFlags, reportErrors, headMessage, intersectionState)
| 64977 | * * Ternary.False if they are not related. |
| 64978 | */ |
| 64979 | function isRelatedTo(originalSource, originalTarget, recursionFlags, reportErrors, headMessage, intersectionState) { |
| 64980 | if (recursionFlags === void 0) { recursionFlags = 3 /* RecursionFlags.Both */; } |
| 64981 | if (reportErrors === void 0) { reportErrors = false; } |
| 64982 | if (intersectionState === void 0) { intersectionState = 0 /* IntersectionState.None */; } |
| 64983 | // Before normalization: if `source` is type an object type, and `target` is primitive, |
| 64984 | // skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result |
| 64985 | if (originalSource.flags & 524288 /* TypeFlags.Object */ && originalTarget.flags & 131068 /* TypeFlags.Primitive */) { |
| 64986 | if (isSimpleTypeRelatedTo(originalSource, originalTarget, relation, reportErrors ? reportError : undefined)) { |
| 64987 | return -1 /* Ternary.True */; |
| 64988 | } |
| 64989 | if (reportErrors) { |
| 64990 | reportErrorResults(originalSource, originalTarget, originalSource, originalTarget, headMessage); |
| 64991 | } |
| 64992 | return 0 /* Ternary.False */; |
| 64993 | } |
| 64994 | // Normalize the source and target types: Turn fresh literal types into regular literal types, |
| 64995 | // turn deferred type references into regular type references, simplify indexed access and |
| 64996 | // conditional types, and resolve substitution types to either the substitution (on the source |
| 64997 | // side) or the type variable (on the target side). |
| 64998 | var source = getNormalizedType(originalSource, /*writing*/ false); |
| 64999 | var target = getNormalizedType(originalTarget, /*writing*/ true); |
| 65000 | if (source === target) |
| 65001 | return -1 /* Ternary.True */; |
| 65002 | if (relation === identityRelation) { |
| 65003 | if (source.flags !== target.flags) |
| 65004 | return 0 /* Ternary.False */; |
| 65005 | if (source.flags & 67358815 /* TypeFlags.Singleton */) |
| 65006 | return -1 /* Ternary.True */; |
| 65007 | traceUnionsOrIntersectionsTooLarge(source, target); |
| 65008 | return recursiveTypeRelatedTo(source, target, /*reportErrors*/ false, 0 /* IntersectionState.None */, recursionFlags); |
| 65009 | } |
| 65010 | // We fastpath comparing a type parameter to exactly its constraint, as this is _super_ common, |
| 65011 | // and otherwise, for type parameters in large unions, causes us to need to compare the union to itself, |
| 65012 | // as we break down the _target_ union first, _then_ get the source constraint - so for every |
| 65013 | // member of the target, we attempt to find a match in the source. This avoids that in cases where |
| 65014 | // the target is exactly the constraint. |
| 65015 | if (source.flags & 262144 /* TypeFlags.TypeParameter */ && getConstraintOfType(source) === target) { |
| 65016 | return -1 /* Ternary.True */; |
| 65017 | } |
| 65018 | // See if we're relating a definitely non-nullable type to a union that includes null and/or undefined |
| 65019 | // plus a single non-nullable type. If so, remove null and/or undefined from the target type. |
| 65020 | if (source.flags & 470302716 /* TypeFlags.DefinitelyNonNullable */ && target.flags & 1048576 /* TypeFlags.Union */) { |
| 65021 | var types = target.types; |
| 65022 | var candidate = types.length === 2 && types[0].flags & 98304 /* TypeFlags.Nullable */ ? types[1] : |
| 65023 | types.length === 3 && types[0].flags & 98304 /* TypeFlags.Nullable */ && types[1].flags & 98304 /* TypeFlags.Nullable */ ? types[2] : |
| 65024 | undefined; |
| 65025 | if (candidate && !(candidate.flags & 98304 /* TypeFlags.Nullable */)) { |
| 65026 | target = getNormalizedType(candidate, /*writing*/ true); |
| 65027 | if (source === target) |
| 65028 | return -1 /* Ternary.True */; |
| 65029 | } |
| 65030 | } |
| 65031 | if (relation === comparableRelation && !(target.flags & 131072 /* TypeFlags.Never */) && isSimpleTypeRelatedTo(target, source, relation) || |
| 65032 | isSimpleTypeRelatedTo(source, target, relation, reportErrors ? reportError : undefined)) |
| 65033 | return -1 /* Ternary.True */; |
| 65034 | if (source.flags & 469499904 /* TypeFlags.StructuredOrInstantiable */ || target.flags & 469499904 /* TypeFlags.StructuredOrInstantiable */) { |
| 65035 | var isPerformingExcessPropertyChecks = !(intersectionState & 2 /* IntersectionState.Target */) && (isObjectLiteralType(source) && ts.getObjectFlags(source) & 8192 /* ObjectFlags.FreshLiteral */); |
| 65036 | if (isPerformingExcessPropertyChecks) { |
no test coverage detected
searching dependent graphs…