diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 76e81a959790b..ba8ec48a39eff 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -25340,11 +25340,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // right is a supertype. const superTypeOrUnion = literalTypesWithSameBaseType(primaryTypes) ? getUnionType(primaryTypes) : - reduceLeft(primaryTypes, (s, t) => isTypeSubtypeOf(s, t) ? t : s)!; + getSingleCommonSupertype(primaryTypes); // Add any nullable types that occurred in the candidates back to the result. return primaryTypes === types ? superTypeOrUnion : getNullableType(superTypeOrUnion, getCombinedTypeFlags(types) & TypeFlags.Nullable); } + function getSingleCommonSupertype(types: Type[]) { + // First, find the leftmost type for which no type to the right is a strict supertype, and if that + // type is a strict supertype of all other candidates, return it. Otherwise, return the leftmost type + // for which no type to the right is a (regular) supertype. + const candidate = reduceLeft(types, (s, t) => isTypeStrictSubtypeOf(s, t) ? t : s)!; + return every(types, t => t === candidate || isTypeStrictSubtypeOf(t, candidate)) ? + candidate : + reduceLeft(types, (s, t) => isTypeSubtypeOf(s, t) ? t : s)!; + } + // Return the leftmost type for which no type to the right is a subtype. function getCommonSubtype(types: Type[]) { return reduceLeft(types, (s, t) => isTypeSubtypeOf(t, s) ? t : s)!;