From 7ec7f02ec3d65d2b37c8d41bcf966ec98bb4ee2e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 23 Mar 2019 10:46:46 -0700 Subject: [PATCH] Instantiate contextual type using non-fixing mapper --- src/compiler/checker.ts | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ea44fb0f3bd..456d5b22325 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -14470,7 +14470,7 @@ namespace ts { const templateType = getTemplateTypeFromMappedType(target); const inference = createInferenceInfo(typeParameter); inferTypes([inference], sourceType, templateType); - return getTypeFromInference(inference); + return getTypeFromInference(inference) || emptyObjectType; } function* getUnmatchedProperties(source: Type, target: Type, requireOptionalProperties: boolean, matchDiscriminantProperties: boolean) { @@ -14514,7 +14514,7 @@ namespace ts { function getTypeFromInference(inference: InferenceInfo) { return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : inference.contraCandidates ? getIntersectionType(inference.contraCandidates) : - emptyObjectType; + undefined; } function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, contravariant = false) { @@ -15016,8 +15016,8 @@ namespace ts { function getInferredType(context: InferenceContext, index: number): Type { const inference = context.inferences[index]; - let inferredType = inference.inferredType; - if (!inferredType) { + if (!inference.inferredType) { + let inferredType: Type | undefined; const signature = context.signature; if (signature) { const inferredCovariantType = inference.candidates ? getCovariantInference(inference, signature) : undefined; @@ -15048,27 +15048,24 @@ namespace ts { // parameter should be instantiated to the empty object type. inferredType = instantiateType(defaultType, combineTypeMappers(createBackreferenceMapper(context, index), context.nonFixingMapper)); } - else { - inferredType = getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault)); - } } } else { inferredType = getTypeFromInference(inference); } - inference.inferredType = inferredType; + inference.inferredType = inferredType || getDefaultTypeArgumentType(!!(context.flags & InferenceFlags.AnyDefault)); const constraint = getConstraintOfTypeParameter(inference.typeParameter); if (constraint) { const instantiatedConstraint = instantiateType(constraint, context.nonFixingMapper); - if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { + if (!inferredType || !context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { inference.inferredType = inferredType = instantiatedConstraint; } } } - return inferredType; + return inference.inferredType; } function getDefaultTypeArgumentType(isInJavaScriptFile: boolean): Type { @@ -18046,8 +18043,13 @@ namespace ts { function instantiateContextualType(contextualType: Type | undefined, node: Expression): Type | undefined { if (contextualType && maybeTypeOfKind(contextualType, TypeFlags.Instantiable)) { const inferenceContext = getInferenceContext(node); - if (inferenceContext && inferenceContext.returnMapper) { - return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper); + if (inferenceContext) { + if ((isFunctionExpressionOrArrowFunction(node) || isObjectLiteralMethod(node)) && isContextSensitive(node)) { + return instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper); + } + if (inferenceContext.returnMapper) { + return instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper); + } } } return contextualType;