@@ -7924,7 +7924,7 @@ namespace ts {
79247924
79257925 function cloneTypeMapper(mapper: TypeMapper): TypeMapper {
79267926 return mapper && isInferenceContext(mapper) ?
7927- createInferenceContext(mapper.callNode, mapper. signature, mapper.flags | InferenceFlags.NoDefault, mapper.inferences) :
7927+ createInferenceContext(mapper.signature, mapper.flags | InferenceFlags.NoDefault, mapper.inferences) :
79287928 mapper;
79297929 }
79307930
@@ -10121,11 +10121,10 @@ namespace ts {
1012110121 }
1012210122 }
1012310123
10124- function createInferenceContext(callNode: CallLikeExpression, signature: Signature, flags: InferenceFlags, baseInferences?: InferenceInfo[]): InferenceContext {
10124+ function createInferenceContext(signature: Signature, flags: InferenceFlags, baseInferences?: InferenceInfo[]): InferenceContext {
1012510125 const inferences = baseInferences ? map(baseInferences, cloneInferenceInfo) : map(signature.typeParameters, createInferenceInfo);
1012610126 const context = mapper as InferenceContext;
1012710127 context.mappedTypes = signature.typeParameters;
10128- context.callNode = callNode;
1012910128 context.signature = signature;
1013010129 context.inferences = inferences;
1013110130 context.flags = flags;
@@ -10302,15 +10301,15 @@ namespace ts {
1030210301 // Even if an inference is marked as fixed, we can add candidates from inferences made
1030310302 // from the return type of generic functions (which only happens when no other candidates
1030410303 // are present).
10305- if (!inference.isFixed || priority & InferencePriority.ReturnType ) {
10304+ if (!inference.isFixed) {
1030610305 if (!inference.candidates || priority < inference.priority) {
1030710306 inference.candidates = [source];
1030810307 inference.priority = priority;
1030910308 }
1031010309 else if (priority === inference.priority) {
1031110310 inference.candidates.push(source);
1031210311 }
10313- if (target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
10312+ if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
1031410313 inference.topLevel = false;
1031510314 }
1031610315 }
@@ -10523,24 +10522,6 @@ namespace ts {
1052310522 let inferredType = inference.inferredType;
1052410523 let inferenceSucceeded: boolean;
1052510524 if (!inferredType) {
10526- if (!inference.candidates && context.callNode && isExpression(context.callNode)) {
10527- // We have no inference candidates. Now attempt to get the contextual type for the call
10528- // expression associated with the context, and if a contextual type is available, infer
10529- // from that type to the return type of the call expression. For example, given a
10530- // 'function wrap<T, U>(cb: (x: T) => U): (x: T) => U' and a call expression
10531- // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type
10532- // of 'f' to the return type of 'wrap'.
10533- const contextualType = getContextualType(context.callNode);
10534- if (contextualType) {
10535- // We clone the contextual mapper to avoid disturbing a resolution in progress for an
10536- // outer call expression. Effectively we just want a snapshot of whatever has been
10537- // inferred for any outer call expression so far.
10538- const mapper = cloneTypeMapper(getContextualMapper(context.callNode));
10539- const instantiatedType = instantiateType(contextualType, mapper);
10540- const returnType = getReturnTypeOfSignature(context.signature);
10541- inferTypes([inference], instantiatedType, returnType, InferencePriority.ReturnType);
10542- }
10543- }
1054410525 if (inference.candidates) {
1054510526 // We widen inferred literal types if
1054610527 // all inferences were made to top-level ocurrences of the type parameter, and
@@ -14866,7 +14847,7 @@ namespace ts {
1486614847
1486714848 // Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
1486814849 function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper: TypeMapper): Signature {
14869- const context = createInferenceContext(/*callNode*/ undefined, signature, InferenceFlags.InferUnionTypes);
14850+ const context = createInferenceContext(signature, InferenceFlags.InferUnionTypes);
1487014851 forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
1487114852 // Type parameters from outer context referenced by source type are fixed by instantiation of the source type
1487214853 inferTypes(context.inferences, instantiateType(source, contextualMapper), target);
@@ -14899,6 +14880,24 @@ namespace ts {
1489914880 context.failedTypeParameterIndex = undefined;
1490014881 }
1490114882
14883+ // If a contextual type is available, infer from that type to the return type of the call expression. For
14884+ // example, given a 'function wrap<T, U>(cb: (x: T) => U): (x: T) => U' and a call expression
14885+ // 'let f: (x: string) => number = wrap(s => s.length)', we infer from the declared type of 'f' to the
14886+ // return type of 'wrap'.
14887+ if (isExpression(node)) {
14888+ const contextualType = getContextualType(node);
14889+ if (contextualType) {
14890+ // We clone the contextual mapper to avoid disturbing a resolution in progress for an
14891+ // outer call expression. Effectively we just want a snapshot of whatever has been
14892+ // inferred for any outer call expression so far.
14893+ const mapper = cloneTypeMapper(getContextualMapper(node));
14894+ const instantiatedType = instantiateType(contextualType, mapper);
14895+ const returnType = getReturnTypeOfSignature(signature);
14896+ // Inferences made from return types have lower priority than all other inferences.
14897+ inferTypes(context.inferences, instantiatedType, returnType, InferencePriority.ReturnType);
14898+ }
14899+ }
14900+
1490214901 const thisType = getThisTypeOfSignature(signature);
1490314902 if (thisType) {
1490414903 const thisArgumentNode = getThisArgumentOfCall(node);
@@ -15599,7 +15598,7 @@ namespace ts {
1559915598 let candidate: Signature;
1560015599 let typeArgumentsAreValid: boolean;
1560115600 const inferenceContext = originalCandidate.typeParameters
15602- ? createInferenceContext(node, originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : 0)
15601+ ? createInferenceContext(originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : 0)
1560315602 : undefined;
1560415603
1560515604 while (true) {
0 commit comments