mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-17 11:24:29 -05:00
Add fastpath to isRelatedTo for type references (#37481)
* Add fastpath to isRelatedTo for type references * Do not check intersections or unions to ignore propegating reference flags, properly set comparing jsx flag * Re-remove unneeded check * Just check for TypeFlags.Object * Remove else clause
This commit is contained in:
@@ -15541,11 +15541,21 @@ namespace ts {
|
||||
* * Ternary.False if they are not related.
|
||||
*/
|
||||
function isRelatedTo(originalSource: Type, originalTarget: Type, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary {
|
||||
// Before normalization: if `source` is type an object type, and `target` is primitive,
|
||||
// skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result
|
||||
if (originalSource.flags & TypeFlags.Object && originalTarget.flags & TypeFlags.Primitive) {
|
||||
if (isSimpleTypeRelatedTo(originalSource, originalTarget, relation, reportErrors ? reportError : undefined)) {
|
||||
return Ternary.True;
|
||||
}
|
||||
reportErrorResults(originalSource, originalTarget, Ternary.False, !!(getObjectFlags(originalSource) & ObjectFlags.JsxAttributes));
|
||||
return Ternary.False;
|
||||
}
|
||||
|
||||
// Normalize the source and target types: Turn fresh literal types into regular literal types,
|
||||
// turn deferred type references into regular type references, simplify indexed access and
|
||||
// conditional types, and resolve substitution types to either the substitution (on the source
|
||||
// side) or the type variable (on the target side).
|
||||
let source = getNormalizedType(originalSource, /*writing*/ false);
|
||||
const source = getNormalizedType(originalSource, /*writing*/ false);
|
||||
let target = getNormalizedType(originalTarget, /*writing*/ true);
|
||||
|
||||
if (source === target) return Ternary.True;
|
||||
@@ -15679,6 +15689,7 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// For certain combinations involving intersections and optional, excess, or mismatched properties we need
|
||||
// an extra property check where the intersection is viewed as a single object. The following are motivating
|
||||
// examples that all should be errors, but aren't without this extra property check:
|
||||
@@ -15702,47 +15713,51 @@ namespace ts {
|
||||
inPropertyCheck = false;
|
||||
}
|
||||
|
||||
if (!result && reportErrors) {
|
||||
source = originalSource.aliasSymbol ? originalSource : source;
|
||||
target = originalTarget.aliasSymbol ? originalTarget : target;
|
||||
let maybeSuppress = overrideNextErrorInfo > 0;
|
||||
if (maybeSuppress) {
|
||||
overrideNextErrorInfo--;
|
||||
}
|
||||
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) {
|
||||
const currentError = errorInfo;
|
||||
tryElaborateArrayLikeErrors(source, target, reportErrors);
|
||||
if (errorInfo !== currentError) {
|
||||
maybeSuppress = !!errorInfo;
|
||||
reportErrorResults(source, target, result, isComparingJsxAttributes);
|
||||
return result;
|
||||
|
||||
function reportErrorResults(source: Type, target: Type, result: Ternary, isComparingJsxAttributes: boolean) {
|
||||
if (!result && reportErrors) {
|
||||
source = originalSource.aliasSymbol ? originalSource : source;
|
||||
target = originalTarget.aliasSymbol ? originalTarget : target;
|
||||
let maybeSuppress = overrideNextErrorInfo > 0;
|
||||
if (maybeSuppress) {
|
||||
overrideNextErrorInfo--;
|
||||
}
|
||||
}
|
||||
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Primitive) {
|
||||
tryElaborateErrorsForPrimitivesAndObjects(source, target);
|
||||
}
|
||||
else if (source.symbol && source.flags & TypeFlags.Object && globalObjectType === source) {
|
||||
reportError(Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead);
|
||||
}
|
||||
else if (isComparingJsxAttributes && target.flags & TypeFlags.Intersection) {
|
||||
const targetTypes = (target as IntersectionType).types;
|
||||
const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode);
|
||||
const intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode);
|
||||
if (intrinsicAttributes !== errorType && intrinsicClassAttributes !== errorType &&
|
||||
(contains(targetTypes, intrinsicAttributes) || contains(targetTypes, intrinsicClassAttributes))) {
|
||||
// do not report top error
|
||||
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) {
|
||||
const currentError = errorInfo;
|
||||
tryElaborateArrayLikeErrors(source, target, reportErrors);
|
||||
if (errorInfo !== currentError) {
|
||||
maybeSuppress = !!errorInfo;
|
||||
}
|
||||
}
|
||||
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Primitive) {
|
||||
tryElaborateErrorsForPrimitivesAndObjects(source, target);
|
||||
}
|
||||
else if (source.symbol && source.flags & TypeFlags.Object && globalObjectType === source) {
|
||||
reportError(Diagnostics.The_Object_type_is_assignable_to_very_few_other_types_Did_you_mean_to_use_the_any_type_instead);
|
||||
}
|
||||
else if (isComparingJsxAttributes && target.flags & TypeFlags.Intersection) {
|
||||
const targetTypes = (target as IntersectionType).types;
|
||||
const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, errorNode);
|
||||
const intrinsicClassAttributes = getJsxType(JsxNames.IntrinsicClassAttributes, errorNode);
|
||||
if (intrinsicAttributes !== errorType && intrinsicClassAttributes !== errorType &&
|
||||
(contains(targetTypes, intrinsicAttributes) || contains(targetTypes, intrinsicClassAttributes))) {
|
||||
// do not report top error
|
||||
return result;
|
||||
}
|
||||
}
|
||||
else {
|
||||
errorInfo = elaborateNeverIntersection(errorInfo, originalTarget);
|
||||
}
|
||||
if (!headMessage && maybeSuppress) {
|
||||
lastSkippedInfo = [source, target];
|
||||
// Used by, eg, missing property checking to replace the top-level message with a more informative one
|
||||
return result;
|
||||
}
|
||||
reportRelationError(headMessage, source, target);
|
||||
}
|
||||
else {
|
||||
errorInfo = elaborateNeverIntersection(errorInfo, originalTarget);
|
||||
}
|
||||
if (!headMessage && maybeSuppress) {
|
||||
lastSkippedInfo = [source, target];
|
||||
// Used by, eg, missing property checking to replace the top-level message with a more informative one
|
||||
return result;
|
||||
}
|
||||
reportRelationError(headMessage, source, target);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function isIdenticalTo(source: Type, target: Type): Ternary {
|
||||
|
||||
Reference in New Issue
Block a user