@@ -7924,7 +7924,7 @@ namespace ts {
7924
7924
7925
7925
function cloneTypeMapper(mapper: TypeMapper): TypeMapper {
7926
7926
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) :
7928
7928
mapper;
7929
7929
}
7930
7930
@@ -10121,11 +10121,10 @@ namespace ts {
10121
10121
}
10122
10122
}
10123
10123
10124
- function createInferenceContext(callNode: CallLikeExpression, signature: Signature, flags: InferenceFlags, baseInferences?: InferenceInfo[]): InferenceContext {
10124
+ function createInferenceContext(signature: Signature, flags: InferenceFlags, baseInferences?: InferenceInfo[]): InferenceContext {
10125
10125
const inferences = baseInferences ? map(baseInferences, cloneInferenceInfo) : map(signature.typeParameters, createInferenceInfo);
10126
10126
const context = mapper as InferenceContext;
10127
10127
context.mappedTypes = signature.typeParameters;
10128
- context.callNode = callNode;
10129
10128
context.signature = signature;
10130
10129
context.inferences = inferences;
10131
10130
context.flags = flags;
@@ -10302,15 +10301,15 @@ namespace ts {
10302
10301
// Even if an inference is marked as fixed, we can add candidates from inferences made
10303
10302
// from the return type of generic functions (which only happens when no other candidates
10304
10303
// are present).
10305
- if (!inference.isFixed || priority & InferencePriority.ReturnType ) {
10304
+ if (!inference.isFixed) {
10306
10305
if (!inference.candidates || priority < inference.priority) {
10307
10306
inference.candidates = [source];
10308
10307
inference.priority = priority;
10309
10308
}
10310
10309
else if (priority === inference.priority) {
10311
10310
inference.candidates.push(source);
10312
10311
}
10313
- if (target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
10312
+ if (!(priority & InferencePriority.ReturnType) && target.flags & TypeFlags.TypeParameter && !isTypeParameterAtTopLevel(originalTarget, <TypeParameter>target)) {
10314
10313
inference.topLevel = false;
10315
10314
}
10316
10315
}
@@ -10523,24 +10522,6 @@ namespace ts {
10523
10522
let inferredType = inference.inferredType;
10524
10523
let inferenceSucceeded: boolean;
10525
10524
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
- }
10544
10525
if (inference.candidates) {
10545
10526
// We widen inferred literal types if
10546
10527
// all inferences were made to top-level ocurrences of the type parameter, and
@@ -14866,7 +14847,7 @@ namespace ts {
14866
14847
14867
14848
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
14868
14849
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);
14870
14851
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
14871
14852
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
14872
14853
inferTypes(context.inferences, instantiateType(source, contextualMapper), target);
@@ -14899,6 +14880,24 @@ namespace ts {
14899
14880
context.failedTypeParameterIndex = undefined;
14900
14881
}
14901
14882
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
+
14902
14901
const thisType = getThisTypeOfSignature(signature);
14903
14902
if (thisType) {
14904
14903
const thisArgumentNode = getThisArgumentOfCall(node);
@@ -15599,7 +15598,7 @@ namespace ts {
15599
15598
let candidate: Signature;
15600
15599
let typeArgumentsAreValid: boolean;
15601
15600
const inferenceContext = originalCandidate.typeParameters
15602
- ? createInferenceContext(node, originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : 0)
15601
+ ? createInferenceContext(originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : 0)
15603
15602
: undefined;
15604
15603
15605
15604
while (true) {
0 commit comments