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