@@ -18652,29 +18652,29 @@ namespace ts {
18652
18652
createTupleType(append(types.slice(0, spreadIndex), getUnionType(types.slice(spreadIndex))), spreadIndex, /*hasRestElement*/ true);
18653
18653
}
18654
18654
18655
- function checkTypeArguments(signature: Signature, typeArgumentNodes: ReadonlyArray<TypeNode>, reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | false {
18655
+ function checkTypeArguments(signature: Signature, typeArgumentNodes: ReadonlyArray<TypeNode>, reportErrors: boolean, headMessage?: DiagnosticMessage): Type[] | undefined {
18656
18656
const isJavascript = isInJavaScriptFile(signature.declaration);
18657
18657
const typeParameters = signature.typeParameters!;
18658
18658
const typeArgumentTypes = fillMissingTypeArguments(map(typeArgumentNodes, getTypeFromTypeNode), typeParameters, getMinTypeArgumentCount(typeParameters), isJavascript);
18659
18659
let mapper: TypeMapper | undefined;
18660
18660
for (let i = 0; i < typeArgumentNodes.length; i++) {
18661
18661
Debug.assert(typeParameters[i] !== undefined, "Should not call checkTypeArguments with too many type arguments");
18662
18662
const constraint = getConstraintOfTypeParameter(typeParameters[i]);
18663
- if (! constraint) continue;
18664
-
18665
- const errorInfo = reportErrors && headMessage ? (() => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1)) : undefined ;
18666
- const typeArgumentHeadMessage = headMessage || Diagnostics.Type_0_does_not_satisfy_the_constraint_1;
18667
- if (! mapper) {
18668
- mapper = createTypeMapper(typeParameters, typeArgumentTypes);
18669
- }
18670
- const typeArgument = typeArgumentTypes[i];
18671
- if (!checkTypeAssignableTo(
18672
- typeArgument,
18673
- getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument) ,
18674
- reportErrors ? typeArgumentNodes[i] : undefined ,
18675
- typeArgumentHeadMessage,
18676
- errorInfo)) {
18677
- return false;
18663
+ if (constraint) {
18664
+ const errorInfo = reportErrors && headMessage ? (() => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Type_0_does_not_satisfy_the_constraint_1)) : undefined;
18665
+ const typeArgumentHeadMessage = headMessage || Diagnostics.Type_0_does_not_satisfy_the_constraint_1;
18666
+ if (!mapper) {
18667
+ mapper = createTypeMapper(typeParameters, typeArgumentTypes);
18668
+ }
18669
+ const typeArgument = typeArgumentTypes[i];
18670
+ if (!checkTypeAssignableTo(
18671
+ typeArgument,
18672
+ getTypeWithThisArgument(instantiateType(constraint, mapper), typeArgument) ,
18673
+ reportErrors ? typeArgumentNodes[i] : undefined ,
18674
+ typeArgumentHeadMessage ,
18675
+ errorInfo)) {
18676
+ return undefined;
18677
+ }
18678
18678
}
18679
18679
}
18680
18680
return typeArgumentTypes;
@@ -19318,54 +19318,58 @@ namespace ts {
19318
19318
}
19319
19319
19320
19320
for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) {
19321
- const originalCandidate = candidates[candidateIndex];
19322
- if (!hasCorrectTypeArgumentArity(originalCandidate , typeArguments) || !hasCorrectArity(node, args!, originalCandidate , signatureHelpTrailingComma)) {
19321
+ const candidate = candidates[candidateIndex];
19322
+ if (!hasCorrectTypeArgumentArity(candidate , typeArguments) || !hasCorrectArity(node, args!, candidate , signatureHelpTrailingComma)) {
19323
19323
continue;
19324
19324
}
19325
19325
19326
- let candidate: Signature;
19327
- const inferenceContext = originalCandidate.typeParameters ?
19328
- createInferenceContext(originalCandidate.typeParameters, originalCandidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None) :
19329
- undefined;
19326
+ let checkCandidate: Signature;
19327
+ let inferenceContext: InferenceContext | undefined;
19330
19328
19331
- while (true) {
19332
- candidate = originalCandidate;
19333
- if (candidate.typeParameters) {
19334
- let typeArgumentTypes: Type[];
19335
- if (typeArguments) {
19336
- const typeArgumentResult = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
19337
- if (typeArgumentResult) {
19338
- typeArgumentTypes = typeArgumentResult;
19339
- }
19340
- else {
19341
- candidateForTypeArgumentError = originalCandidate;
19342
- break;
19343
- }
19344
- }
19345
- else {
19346
- typeArgumentTypes = inferTypeArguments(node, candidate, args!, excludeArgument, inferenceContext!);
19347
- }
19348
- const isJavascript = isInJavaScriptFile(candidate.declaration);
19349
- candidate = getSignatureInstantiation(candidate, typeArgumentTypes, isJavascript);
19350
- // If the original signature has a generic rest type, instantiation may produce a
19351
- // signature with different arity and we need to perform another arity check.
19352
- if (getGenericRestType(originalCandidate) && !hasCorrectArity(node, args!, candidate, signatureHelpTrailingComma)) {
19353
- candidateForArgumentArityError = candidate;
19354
- break;
19329
+ if (candidate.typeParameters) {
19330
+ let typeArgumentTypes: Type[] | undefined;
19331
+ if (typeArguments) {
19332
+ typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false);
19333
+ if (!typeArgumentTypes) {
19334
+ candidateForTypeArgumentError = candidate;
19335
+ continue;
19355
19336
}
19356
19337
}
19357
- if (!checkApplicableSignature(node, args!, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
19358
- candidateForArgumentError = candidate;
19359
- break;
19360
- }
19361
- // If no arguments were excluded, we're done
19362
- if (!excludeArgument) {
19363
- candidates[candidateIndex] = candidate;
19364
- return candidate;
19338
+ else {
19339
+ inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJavaScriptFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None);
19340
+ typeArgumentTypes = inferTypeArguments(node, candidate, args!, excludeArgument, inferenceContext);
19341
+ }
19342
+ checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJavaScriptFile(candidate.declaration));
19343
+ // If the original signature has a generic rest type, instantiation may produce a
19344
+ // signature with different arity and we need to perform another arity check.
19345
+ if (getGenericRestType(candidate) && !hasCorrectArity(node, args!, checkCandidate, signatureHelpTrailingComma)) {
19346
+ candidateForArgumentArityError = checkCandidate;
19347
+ continue;
19365
19348
}
19366
- // Otherwise, stop excluding arguments and perform a second pass
19349
+ }
19350
+ else {
19351
+ checkCandidate = candidate;
19352
+ }
19353
+ if (!checkApplicableSignature(node, args!, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
19354
+ candidateForArgumentError = checkCandidate;
19355
+ continue;
19356
+ }
19357
+ if (excludeArgument) {
19358
+ // If one or more context sensitive arguments were excluded, we start including
19359
+ // them now (and keeping do so for any subsequent candidates) and perform a second
19360
+ // round of type inference and applicability checking for this particular candidate.
19367
19361
excludeArgument = undefined;
19362
+ if (inferenceContext) {
19363
+ const typeArgumentTypes = inferTypeArguments(node, candidate, args!, excludeArgument, inferenceContext);
19364
+ checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJavaScriptFile(candidate.declaration));
19365
+ }
19366
+ if (!checkApplicableSignature(node, args!, checkCandidate, relation, excludeArgument, /*reportErrors*/ false)) {
19367
+ candidateForArgumentError = checkCandidate;
19368
+ continue;
19369
+ }
19368
19370
}
19371
+ candidates[candidateIndex] = checkCandidate;
19372
+ return checkCandidate;
19369
19373
}
19370
19374
19371
19375
return undefined;
0 commit comments