From ca47ddb583fb1605f4923fadd38703f6d1ed9993 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 10 Apr 2019 17:41:51 -1000 Subject: [PATCH] Only infer to single naked type parameters in intersections --- src/compiler/checker.ts | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 79480be336d..b75f0c39af3 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14773,22 +14773,29 @@ namespace ts { // 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. + let typeVariableCount = 0; for (const t of (target).types) { - if (!getInferenceInfoForType(t)) { + if (getInferenceInfoForType(t)) { + typeVariableCount++; + } + else { inferFromTypes(source, t); } } // 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); + // we want to infer string for T, not Promise | string. For intersection types + // we only infer to single naked type variables. + if (target.flags & TypeFlags.Union ? typeVariableCount !== 0 : typeVariableCount === 1) { + const savePriority = priority; + priority |= InferencePriority.NakedTypeVariable; + for (const t of (target).types) { + if (getInferenceInfoForType(t)) { + inferFromTypes(source, t); + } } + priority = savePriority; } - priority = savePriority; } else if (source.flags & TypeFlags.Union) { // Source is a union or intersection type, infer from each constituent type