Skip to content

Commit b19c64d

Browse files
committed
Optimize getNarrowedTypeWorker for literals
1 parent 9473195 commit b19c64d

File tree

1 file changed

+34
-4
lines changed

1 file changed

+34
-4
lines changed

src/compiler/checker.ts

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16782,7 +16782,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1678216782
// a subtype of just `A` or just `B`. When we encounter such a type parameter, we therefore check if the
1678316783
// type parameter is a subtype of a union of all the other types.
1678416784
if (source.flags & TypeFlags.TypeParameter && getBaseConstraintOrType(source).flags & TypeFlags.Union) {
16785-
if (isTypeRelatedTo(source, getUnionType(map(types, t => t === source ? neverType : t)), strictSubtypeRelation)) {
16785+
if (isTypeStrictSubtypeOf(source, getUnionType(map(types, t => t === source ? neverType : t)))) {
1678616786
orderedRemoveItemAt(types, i);
1678716787
}
1678816788
continue;
@@ -16816,7 +16816,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
1681616816
}
1681716817
}
1681816818
if (
16819-
isTypeRelatedTo(source, target, strictSubtypeRelation) && (
16819+
isTypeStrictSubtypeOf(source, target) && (
1682016820
!(getObjectFlags(getTargetType(source)) & ObjectFlags.Class) ||
1682116821
!(getObjectFlags(getTargetType(target)) & ObjectFlags.Class) ||
1682216822
isTypeDerivedFrom(source, target)
@@ -28042,7 +28042,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2804228042
// the constituent based on its type facts. We use the strict subtype relation because it treats `object`
2804328043
// as a subtype of `{}`, and we need the type facts check because function types are subtypes of `object`,
2804428044
// but are classified as "function" according to `typeof`.
28045-
isTypeRelatedTo(t, impliedType, strictSubtypeRelation) ? hasTypeFacts(t, facts) ? t : neverType :
28045+
isTypeStrictSubtypeOf(t, impliedType) ? hasTypeFacts(t, facts) ? t : neverType :
2804628046
// We next check if the consituent is a supertype of the implied type. If so, we substitute the implied
2804728047
// type. This handles top types like `unknown` and `{}`, and supertypes like `{ toString(): string }`.
2804828048
isTypeSubtypeOf(impliedType, t) ? impliedType :
@@ -28240,7 +28240,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2824028240
matching || type,
2824128241
checkDerived ?
2824228242
t => isTypeDerivedFrom(t, c) ? t : isTypeDerivedFrom(c, t) ? c : neverType :
28243-
t => isTypeStrictSubtypeOf(t, c) ? t : isTypeStrictSubtypeOf(c, t) ? c : isTypeSubtypeOf(t, c) ? t : isTypeSubtypeOf(c, t) ? c : neverType,
28243+
t => {
28244+
// isTypeStrictSubtypeOf(t, c) ? t : isTypeStrictSubtypeOf(c, t) ? c : isTypeSubtypeOf(t, c) ? t : isTypeSubtypeOf(c, t) ? c : neverType;
28245+
28246+
if (t.flags & TypeFlags.Literal && c.flags & TypeFlags.Literal) {
28247+
if (t.flags & TypeFlags.BooleanLiteral && c.flags & TypeFlags.BooleanLiteral) {
28248+
return t === c ? t : neverType;
28249+
}
28250+
return (t as LiteralType).value === (c as LiteralType).value ? t : neverType;
28251+
}
28252+
28253+
if (isTypeStrictSubtypeOf(t, c)) return t;
28254+
if (isTypeStrictSubtypeOf(c, t)) return c;
28255+
28256+
if (t.flags & TypeFlags.Unit && c.flags & TypeFlags.Unit) return neverType;
28257+
28258+
if (isTypeSubtypeOf(t, c)) return t;
28259+
if (isTypeSubtypeOf(c, t)) return c;
28260+
28261+
return neverType;
28262+
},
2824428263
);
2824528264
// If no constituents are directly related, create intersections for any generic constituents that
2824628265
// are related by constraint.
@@ -28257,6 +28276,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2825728276
getIntersectionType([type, candidate]);
2825828277
}
2825928278

28279+
// function strictSubtypeImpliesSubtype(source: Type, target: Type) {
28280+
// const s = source.flags;
28281+
// const t = target.flags;
28282+
// if (
28283+
// !(t & TypeFlags.Unknown && !(s & TypeFlags.Any))
28284+
// || !(s & TypeFlags.Object && t & TypeFlags.NonPrimitive && !(isEmptyAnonymousObjectType(source) && !(getObjectFlags(source) & ObjectFlags.FreshLiteral)))
28285+
// ) return false;
28286+
28287+
// return true;
28288+
// }
28289+
2826028290
function narrowTypeByCallExpression(type: Type, callExpression: CallExpression, assumeTrue: boolean): Type {
2826128291
if (hasMatchingArgument(callExpression, reference)) {
2826228292
const signature = assumeTrue || !isCallChain(callExpression) ? getEffectsSignature(callExpression) : undefined;

0 commit comments

Comments
 (0)