From e6a50a78619632bba7af4f23b2e7e4940b9cf788 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Tue, 24 Jun 2025 15:38:59 -0700 Subject: [PATCH] Use strict subtype relation in `getCommonSupertype` (#61903) --- src/compiler/checker.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 76e81a95979..ba8ec48a39e 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)!;