From f93f8d32c45d0c91310efce5d55c19750732a11e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 5 Apr 2019 13:23:54 -0700 Subject: [PATCH] Tweak union type inference to restore previous behavior --- src/compiler/checker.ts | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index febb8ffdad3..bee2e3437a2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14724,17 +14724,25 @@ namespace ts { inferFromTypes(source, (target).falseType); } else if (target.flags & TypeFlags.UnionOrIntersection) { + // We infer from types that are not naked type variables first so that inferences we + // make from nested naked type variables and given slightly higher priority by virtue + // of being first in the candidates array. for (const t of (target).types) { - const savePriority = priority; - // Inferences directly to naked type variables are given lower priority as they are - // less specific. For example, when inferring from Promise to T | Promise, - // we want to infer string for T, not Promise | string. - if (getInferenceInfoForType(t)) { - priority |= InferencePriority.NakedTypeVariable; + if (!getInferenceInfoForType(t)) { + inferFromTypes(source, t); } - inferFromTypes(source, t); - priority = savePriority; } + // Inferences directly to naked type variables are given lower priority as they are + // less specific. For example, when inferring from Promise to T | Promise, + // we want to infer string for T, not Promise | string. + const savePriority = priority; + priority |= InferencePriority.NakedTypeVariable; + for (const t of (target).types) { + if (getInferenceInfoForType(t)) { + inferFromTypes(source, t); + } + } + priority = savePriority; } else if (source.flags & TypeFlags.Union) { // Source is a union or intersection type, infer from each constituent type