@@ -7937,6 +7937,10 @@ namespace ts {
7937
7937
return context.mapper;
7938
7938
}
7939
7939
7940
+ function cloneTypeMapper(mapper: TypeMapper): TypeMapper {
7941
+ return mapper && mapper.context ? getInferenceMapper(cloneInferenceContext(mapper.context)) : mapper;
7942
+ }
7943
+
7940
7944
function identityMapper(type: Type): Type {
7941
7945
return type;
7942
7946
}
@@ -10130,12 +10134,13 @@ namespace ts {
10130
10134
}
10131
10135
}
10132
10136
10133
- function createInferenceContext(signature: Signature, inferUnionTypes: boolean, useAnyForNoInferences: boolean ): InferenceContext {
10137
+ function createInferenceContext(callNode: CallLikeExpression, signature: Signature, inferUnionTypes: boolean, noInferenceType: Type ): InferenceContext {
10134
10138
return {
10139
+ callNode,
10135
10140
signature,
10136
10141
inferences: map(signature.typeParameters, createInferenceInfo),
10137
10142
inferUnionTypes,
10138
- useAnyForNoInferences
10143
+ noInferenceType
10139
10144
};
10140
10145
}
10141
10146
@@ -10150,6 +10155,27 @@ namespace ts {
10150
10155
};
10151
10156
}
10152
10157
10158
+ function cloneInferenceContext(context: InferenceContext): InferenceContext {
10159
+ return {
10160
+ callNode: context.callNode,
10161
+ signature: context.signature,
10162
+ inferences: map(context.inferences, cloneInferenceInfo),
10163
+ inferUnionTypes: context.inferUnionTypes,
10164
+ noInferenceType: silentNeverType
10165
+ }
10166
+ }
10167
+
10168
+ function cloneInferenceInfo(inference: InferenceInfo): InferenceInfo {
10169
+ return {
10170
+ typeParameter: inference.typeParameter,
10171
+ candidates: inference.candidates && inference.candidates.slice(),
10172
+ inferredType: inference.inferredType,
10173
+ priority: inference.priority,
10174
+ topLevel: inference.topLevel,
10175
+ isFixed: inference.isFixed
10176
+ };
10177
+ }
10178
+
10153
10179
// Return true if the given type could possibly reference a type parameter for which
10154
10180
// we perform type inference (i.e. a type parameter of a generic function). We cache
10155
10181
// results for union and intersection types for performance reasons.
@@ -10221,10 +10247,9 @@ namespace ts {
10221
10247
inferTypes(context.inferences, originalSource, originalTarget);
10222
10248
}
10223
10249
10224
- function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type) {
10250
+ function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0 ) {
10225
10251
let symbolStack: Symbol[];
10226
10252
let visited: Map<boolean>;
10227
- let priority = 0;
10228
10253
inferFromTypes(originalSource, originalTarget);
10229
10254
10230
10255
function inferFromTypes(source: Type, target: Type) {
@@ -10285,7 +10310,7 @@ namespace ts {
10285
10310
// it as an inference candidate. Hopefully, a better candidate will come along that does
10286
10311
// not contain anyFunctionType when we come back to this argument for its second round
10287
10312
// of inference.
10288
- if (source.flags & TypeFlags.ContainsAnyFunctionType) {
10313
+ if (source.flags & TypeFlags.ContainsAnyFunctionType || source === silentNeverType ) {
10289
10314
return;
10290
10315
}
10291
10316
for (const inference of inferences) {
@@ -10517,8 +10542,19 @@ namespace ts {
10517
10542
let inferredType = inference.inferredType;
10518
10543
let inferenceSucceeded: boolean;
10519
10544
if (!inferredType) {
10520
- const candidates = inference.candidates;
10521
- if (candidates) {
10545
+ if (!inference.candidates && context.callNode && isExpression(context.callNode)) {
10546
+ const contextualType = getContextualType(context.callNode);
10547
+ if (contextualType) {
10548
+ const mapper = cloneTypeMapper(getContextualMapper(context.callNode));
10549
+ const instantiatedType = instantiateType(contextualType, mapper);
10550
+ const returnType = getReturnTypeOfSignature(context.signature);
10551
+ const saveFixed = inference.isFixed;
10552
+ inference.isFixed = false;
10553
+ inferTypes([inference], instantiatedType, returnType, InferencePriority.ReturnType);
10554
+ inference.isFixed = saveFixed;
10555
+ }
10556
+ }
10557
+ if (inference.candidates) {
10522
10558
// We widen inferred literal types if
10523
10559
// all inferences were made to top-level ocurrences of the type parameter, and
10524
10560
// the type parameter has no constraint or its constraint includes no primitive or literal types, and
@@ -10527,7 +10563,7 @@ namespace ts {
10527
10563
const widenLiteralTypes = inference.topLevel &&
10528
10564
!hasPrimitiveConstraint(inference.typeParameter) &&
10529
10565
(inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter));
10530
- const baseCandidates = widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : candidates;
10566
+ const baseCandidates = widenLiteralTypes ? sameMap(inference. candidates, getWidenedLiteralType) : inference. candidates;
10531
10567
// Infer widened union or supertype, or the unknown type for no common supertype
10532
10568
const unionOrSuperType = context.inferUnionTypes ? getUnionType(baseCandidates, /*subtypeReduction*/ true) : getCommonSupertype(baseCandidates);
10533
10569
inferredType = unionOrSuperType ? getWidenedType(unionOrSuperType) : unknownType;
@@ -10539,7 +10575,7 @@ namespace ts {
10539
10575
// succeeds, meaning there is no error for not having inference candidates. An
10540
10576
// inference error only occurs when there are *conflicting* candidates, i.e.
10541
10577
// candidates with no common supertype.
10542
- const defaultType = getDefaultFromTypeParameter(inference.typeParameter);
10578
+ const defaultType = context.noInferenceType === silentNeverType ? undefined : getDefaultFromTypeParameter(inference.typeParameter);
10543
10579
if (defaultType) {
10544
10580
// Instantiate the default type. Any forward reference to a type
10545
10581
// parameter should be instantiated to the empty object type.
@@ -10549,7 +10585,7 @@ namespace ts {
10549
10585
getInferenceMapper(context)));
10550
10586
}
10551
10587
else {
10552
- inferredType = context.useAnyForNoInferences ? anyType : emptyObjectType ;
10588
+ inferredType = context.noInferenceType ;
10553
10589
}
10554
10590
10555
10591
inferenceSucceeded = true;
@@ -14836,7 +14872,7 @@ namespace ts {
14836
14872
14837
14873
// Instantiate a generic signature in the context of a non-generic signature (section 3.8.5 in TypeScript spec)
14838
14874
function instantiateSignatureInContextOf(signature: Signature, contextualSignature: Signature, contextualMapper: TypeMapper): Signature {
14839
- const context = createInferenceContext(signature, /*inferUnionTypes*/ true, /*useAnyForNoInferences */ false );
14875
+ const context = createInferenceContext(/*callNode*/ undefined, signature, /*inferUnionTypes*/ true, /*noInferenceType */ emptyObjectType );
14840
14876
forEachMatchingParameterType(contextualSignature, signature, (source, target) => {
14841
14877
// Type parameters from outer context referenced by source type are fixed by instantiation of the source type
14842
14878
inferTypesWithContext(context, instantiateType(source, contextualMapper), target);
@@ -15570,7 +15606,7 @@ namespace ts {
15570
15606
let candidate: Signature;
15571
15607
let typeArgumentsAreValid: boolean;
15572
15608
const inferenceContext = originalCandidate.typeParameters
15573
- ? createInferenceContext(originalCandidate, /*inferUnionTypes*/ false, /*useAnyForNoInferences */ isInJavaScriptFile(node))
15609
+ ? createInferenceContext(node, originalCandidate, /*inferUnionTypes*/ false, /*noInferenceType */ isInJavaScriptFile(node) ? anyType : emptyObjectType )
15574
15610
: undefined;
15575
15611
15576
15612
while (true) {
0 commit comments