Skip to content

Commit f5f8a45

Browse files
committed
Optimize checkTypeRelatedTo
1 parent 1868f2e commit f5f8a45

1 file changed

Lines changed: 51 additions & 6 deletions

File tree

src/compiler/checker.ts

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5779,31 +5779,31 @@ namespace ts {
57795779
// TYPE CHECKING
57805780

57815781
function isTypeIdenticalTo(source: Type, target: Type): boolean {
5782-
return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined);
5782+
return isTypeRelatedTo(source, target, identityRelation);
57835783
}
57845784

57855785
function compareTypesIdentical(source: Type, target: Type): Ternary {
5786-
return checkTypeRelatedTo(source, target, identityRelation, /*errorNode*/ undefined) ? Ternary.True : Ternary.False;
5786+
return isTypeRelatedTo(source, target, identityRelation) ? Ternary.True : Ternary.False;
57875787
}
57885788

57895789
function compareTypesAssignable(source: Type, target: Type): Ternary {
5790-
return checkTypeRelatedTo(source, target, assignableRelation, /*errorNode*/ undefined) ? Ternary.True : Ternary.False;
5790+
return isTypeRelatedTo(source, target, assignableRelation) ? Ternary.True : Ternary.False;
57915791
}
57925792

57935793
function isTypeSubtypeOf(source: Type, target: Type): boolean {
5794-
return checkTypeSubtypeOf(source, target, /*errorNode*/ undefined);
5794+
return isTypeRelatedTo(source, target, subtypeRelation);
57955795
}
57965796

57975797
function isTypeAssignableTo(source: Type, target: Type): boolean {
5798-
return checkTypeAssignableTo(source, target, /*errorNode*/ undefined);
5798+
return isTypeRelatedTo(source, target, assignableRelation);
57995799
}
58005800

58015801
/**
58025802
* This is *not* a bi-directional relationship.
58035803
* If one needs to check both directions for comparability, use a second call to this function or 'checkTypeComparableTo'.
58045804
*/
58055805
function isTypeComparableTo(source: Type, target: Type): boolean {
5806-
return checkTypeComparableTo(source, target, /*errorNode*/ undefined);
5806+
return isTypeRelatedTo(source, target, comparableRelation);
58075807
}
58085808

58095809
function areTypesComparable(type1: Type, type2: Type): boolean {
@@ -5996,6 +5996,51 @@ namespace ts {
59965996
}
59975997
}
59985998

5999+
function isPrimtiveTypeRelatedTo(source: Type, target: Type, relation: Map<RelationComparisonResult>) {
6000+
if (target.flags & TypeFlags.Any || source.flags & TypeFlags.Never) return true;
6001+
if (source.flags & TypeFlags.Undefined) {
6002+
if (!strictNullChecks || target.flags & (TypeFlags.Undefined | TypeFlags.Void)) return true;
6003+
}
6004+
if (source.flags & TypeFlags.Null) {
6005+
if (!strictNullChecks || target.flags & TypeFlags.Null) return true;
6006+
}
6007+
if (source.flags & TypeFlags.NumberLike && target === numberType) return true;
6008+
if (source.flags & TypeFlags.Enum && target.flags & TypeFlags.Enum && source.symbol.flags & SymbolFlags.EnumMember && source.symbol.parent === target.symbol) {
6009+
return true;
6010+
}
6011+
if (source.flags & TypeFlags.StringLike && target === stringType) return true;
6012+
if (relation === assignableRelation || relation === comparableRelation) {
6013+
if (source.flags & TypeFlags.Any) return true;
6014+
if (source === numberType && target.flags & TypeFlags.Enum) return true;
6015+
}
6016+
if (source.flags & TypeFlags.BooleanLike && target.flags & TypeFlags.Boolean) return true;
6017+
return false;
6018+
}
6019+
6020+
function isTypeRelatedTo(source: Type, target: Type, relation: Map<RelationComparisonResult>) {
6021+
if (source === target) {
6022+
return true;
6023+
}
6024+
if (relation !== identityRelation) {
6025+
if (source.flags & TypeFlags.Primitive && target.flags & TypeFlags.Primitive) {
6026+
if (isPrimtiveTypeRelatedTo(source, target, relation)) {
6027+
return true;
6028+
}
6029+
if (!(source.flags & TypeFlags.Union || target.flags & TypeFlags.Union)) {
6030+
return false;
6031+
}
6032+
}
6033+
}
6034+
if (source.flags & TypeFlags.ObjectType && target.flags & TypeFlags.ObjectType) {
6035+
const id = relation !== identityRelation || source.id < target.id ? source.id + "," + target.id : target.id + "," + source.id;
6036+
const related = relation[id];
6037+
if (related !== undefined) {
6038+
return related === RelationComparisonResult.Succeeded;
6039+
}
6040+
}
6041+
return checkTypeRelatedTo(source, target, relation, undefined, undefined, undefined);
6042+
}
6043+
59996044
/**
60006045
* Checks if 'source' is related to 'target' (e.g.: is a assignable to).
60016046
* @param source The left-hand-side of the relation.

0 commit comments

Comments
 (0)