@@ -11671,12 +11671,14 @@ namespace ts {
11671
11671
return checkTypeRelatedToAndOptionallyElaborate(source, target, assignableRelation, errorNode, expr, headMessage, containingMessageChain);
11672
11672
}
11673
11673
11674
- function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map<RelationComparisonResult>, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean {
11675
- if (isTypeRelatedTo(source, target, relation)) return true;
11674
+ function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map<RelationComparisonResult>, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean;
11675
+ function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map<RelationComparisonResult>, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined, breakdown?: boolean): [Node, DiagnosticMessageChain];
11676
+ function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map<RelationComparisonResult>, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined, breakdown?: boolean): boolean | [Node, DiagnosticMessageChain] {
11677
+ if (isTypeRelatedTo(source, target, relation)) return breakdown ? false : true;
11676
11678
if (!errorNode || !elaborateError(expr, source, target, relation, headMessage)) {
11677
- return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain);
11679
+ return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain, undefined, breakdown );
11678
11680
}
11679
- return false;
11681
+ return breakdown ? [undefined!,undefined!] as [Node, DiagnosticMessageChain] : false;
11680
11682
}
11681
11683
11682
11684
function isOrHasGenericConditional(type: Type): boolean {
@@ -12430,7 +12432,10 @@ namespace ts {
12430
12432
}
12431
12433
diagnostics.add(diag); // TODO: GH#18217
12432
12434
}
12433
- Debug.assert(!breakdown);
12435
+ if (breakdown) {
12436
+ Debug.assert(result === Ternary.False ? !errorNode : true, "missed opportunity to interact with error.");
12437
+ return result === Ternary.False ? [undefined!, undefined!] as [Node, DiagnosticMessageChain] : false;
12438
+ }
12434
12439
return result !== Ternary.False;
12435
12440
12436
12441
function reportError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void {
@@ -21121,13 +21126,13 @@ namespace ts {
21121
21126
// can be specified by users through attributes property.
21122
21127
const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node);
21123
21128
const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode);
21124
- return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes);
21129
+ return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes, undefined, undefined, /*breakdown*/ true );
21125
21130
}
21126
21131
21127
21132
// TODO: This function is only used in overload resolution; it should instead return a [errorNode, messageChain] pair if there is a failure and undefined if not
21128
21133
// The first-round callers can used undefined=pass and the second-round callers can build their own errors from the pair.
21129
21134
// TODO: Still need to thread BREAKDOWN through checkTypeRealtedToAndOptionallyElaborate and all other checkType calls
21130
- function checkApplicableSignature (
21135
+ function getSignatureApplicabilityError (
21131
21136
node: CallLikeExpression,
21132
21137
args: ReadonlyArray<Expression>,
21133
21138
signature: Signature,
@@ -21149,8 +21154,9 @@ namespace ts {
21149
21154
const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType;
21150
21155
const errorNode = reportErrors ? (thisArgumentNode || node) : undefined;
21151
21156
const headMessage = Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1;
21152
- if (!checkTypeRelatedTo(thisArgumentType, thisType, relation, errorNode, headMessage)) {
21153
- return false;
21157
+ const r = checkTypeRelatedTo(thisArgumentType, thisType, relation, errorNode, headMessage, undefined, undefined, /*breakdown*/ true);
21158
+ if (r) {
21159
+ return r;
21154
21160
}
21155
21161
}
21156
21162
const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1;
@@ -21165,17 +21171,18 @@ namespace ts {
21165
21171
// we obtain the regular type of any object literal arguments because we may not have inferred complete
21166
21172
// parameter types yet and therefore excess property checks may yield false positives (see #17041).
21167
21173
const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType;
21168
- if (!checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage, containingMessageChain)) {
21169
- return false;
21174
+ const r = checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage, containingMessageChain, /*breakdown*/ true);
21175
+ if (r) {
21176
+ return r;
21170
21177
}
21171
21178
}
21172
21179
}
21173
21180
if (restType) {
21174
21181
const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined);
21175
21182
const errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined;
21176
- return checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage);
21183
+ return checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, undefined, undefined, /*breakdown*/ true );
21177
21184
}
21178
- return true ;
21185
+ return undefined ;
21179
21186
}
21180
21187
21181
21188
/**
@@ -21506,13 +21513,15 @@ namespace ts {
21506
21513
if (candidatesForArgumentError.length > 3) {
21507
21514
const c = candidatesForArgumentError[candidatesForArgumentError.length - 1];
21508
21515
const chain = chainDiagnosticMessages(undefined, Diagnostics.Failed_to_find_a_suitable_overload_for_this_call);
21509
- checkApplicableSignature (node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain);
21516
+ getSignatureApplicabilityError (node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain);
21510
21517
}
21511
21518
else {
21512
21519
// const related: DiagnosticRelatedInformation[] = [];
21513
21520
for (const c of candidatesForArgumentError) {
21514
21521
const chain = chainDiagnosticMessages(chainDiagnosticMessages(undefined, Diagnostics.Overload_0_gave_the_following_error, signatureToString(c)), Diagnostics.Failed_to_find_a_suitable_overload_for_this_call);
21515
- const [errorNode, msg] = checkApplicableSignature(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain);
21522
+ const r = getSignatureApplicabilityError(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain);
21523
+ if (!r || !r[0]) continue; // TODO:assert!
21524
+ diagnostics.add(createDiagnosticForNodeFromMessageChain(r[0], r[1], /*relatedInformation*/ undefined));
21516
21525
// related.push(argNode)
21517
21526
// This is not right; I want them to be siblings
21518
21527
// probably this is a new feature :(
@@ -21552,7 +21561,7 @@ namespace ts {
21552
21561
if (typeArguments || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) {
21553
21562
return undefined;
21554
21563
}
21555
- if (!checkApplicableSignature (node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
21564
+ if (getSignatureApplicabilityError (node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
21556
21565
candidatesForArgumentError = [candidate];
21557
21566
return undefined;
21558
21567
}
@@ -21593,7 +21602,7 @@ namespace ts {
21593
21602
else {
21594
21603
checkCandidate = candidate;
21595
21604
}
21596
- if (!checkApplicableSignature (node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
21605
+ if (getSignatureApplicabilityError (node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
21597
21606
// Give preference to error candidates that have no rest parameters (as they are more specific)
21598
21607
if (getMinArgumentCount(checkCandidate) <= args.length && args.length <= getParameterCount(checkCandidate)) {
21599
21608
(candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
@@ -21615,7 +21624,7 @@ namespace ts {
21615
21624
continue;
21616
21625
}
21617
21626
}
21618
- if (!checkApplicableSignature (node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
21627
+ if (getSignatureApplicabilityError (node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) {
21619
21628
// Give preference to error candidates that have no rest parameters (as they are more specific)
21620
21629
if (getMinArgumentCount(checkCandidate) <= args.length && args.length <= getParameterCount(checkCandidate)) {
21621
21630
(candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate);
0 commit comments