@@ -12341,7 +12341,26 @@ namespace ts {
12341
12341
return getObjectFlags(source) & ObjectFlags.JsxAttributes && !isUnhyphenatedJsxName(sourceProp.escapedName);
12342
12342
}
12343
12343
12344
- /**
12344
+ function checkTypeRelatedTo(
12345
+ source: Type,
12346
+ target: Type,
12347
+ relation: Map<RelationComparisonResult>,
12348
+ errorNode: Node | undefined,
12349
+ headMessage?: DiagnosticMessage,
12350
+ containingMessageChain?: () => DiagnosticMessageChain | undefined,
12351
+ errorOutputContainer?: { error?: Diagnostic },
12352
+ ): boolean;
12353
+ function checkTypeRelatedTo(
12354
+ source: Type,
12355
+ target: Type,
12356
+ relation: Map<RelationComparisonResult>,
12357
+ errorNode: Node | undefined,
12358
+ headMessage?: DiagnosticMessage,
12359
+ containingMessageChain?: () => DiagnosticMessageChain | undefined,
12360
+ errorOutputContainer?: { error?: Diagnostic },
12361
+ breakdown?: boolean
12362
+ ): [Node, DiagnosticMessageChain];
12363
+ /**
12345
12364
* Checks if 'source' is related to 'target' (e.g.: is a assignable to).
12346
12365
* @param source The left-hand-side of the relation.
12347
12366
* @param target The right-hand-side of the relation.
@@ -12358,9 +12377,9 @@ namespace ts {
12358
12377
errorNode: Node | undefined,
12359
12378
headMessage?: DiagnosticMessage,
12360
12379
containingMessageChain?: () => DiagnosticMessageChain | undefined,
12361
- errorOutputContainer?: { error?: Diagnostic }
12362
- ) : boolean {
12363
-
12380
+ errorOutputContainer?: { error?: Diagnostic },
12381
+ breakdown? : boolean
12382
+ ): boolean | [Node, DiagnosticMessageChain] {
12364
12383
let errorInfo: DiagnosticMessageChain | undefined;
12365
12384
let relatedInfo: [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] | undefined;
12366
12385
let maybeKeys: string[];
@@ -12399,7 +12418,9 @@ namespace ts {
12399
12418
}
12400
12419
}
12401
12420
}
12402
-
12421
+ if (breakdown) {
12422
+ return [errorNode!, errorInfo];
12423
+ }
12403
12424
const diag = createDiagnosticForNodeFromMessageChain(errorNode!, errorInfo, relatedInformation);
12404
12425
if (relatedInfo) {
12405
12426
addRelatedInfo(diag, ...relatedInfo);
@@ -12409,6 +12430,7 @@ namespace ts {
12409
12430
}
12410
12431
diagnostics.add(diag); // TODO: GH#18217
12411
12432
}
12433
+ Debug.assert(!breakdown);
12412
12434
return result !== Ternary.False;
12413
12435
12414
12436
function reportError(message: DiagnosticMessage, arg0?: string | number, arg1?: string | number, arg2?: string | number, arg3?: string | number): void {
@@ -21102,14 +21124,17 @@ namespace ts {
21102
21124
return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes);
21103
21125
}
21104
21126
21127
+ // 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
+ // The first-round callers can used undefined=pass and the second-round callers can build their own errors from the pair.
21129
+ // TODO: Still need to thread BREAKDOWN through checkTypeRealtedToAndOptionallyElaborate and all other checkType calls
21105
21130
function checkApplicableSignature(
21106
21131
node: CallLikeExpression,
21107
21132
args: ReadonlyArray<Expression>,
21108
21133
signature: Signature,
21109
21134
relation: Map<RelationComparisonResult>,
21110
21135
checkMode: CheckMode,
21111
21136
reportErrors: boolean,
21112
- containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined
21137
+ containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined,
21113
21138
) {
21114
21139
if (isJsxOpeningLikeElement(node)) {
21115
21140
// TODO: Maybe containingMessageChain too?
@@ -21478,14 +21503,21 @@ namespace ts {
21478
21503
// skip the checkApplicableSignature check.
21479
21504
if (reportErrors) {
21480
21505
if (candidatesForArgumentError) {
21481
- // const related: DiagnosticRelatedInformation[] = [];
21482
- for ( const c of candidatesForArgumentError) {
21483
- const chain = chainDiagnosticMessages(chainDiagnosticMessages( undefined, Diagnostics.Overload_0_gave_the_following_error, signatureToString(c)) , Diagnostics.Failed_to_find_a_suitable_overload_for_this_call);
21506
+ if (candidatesForArgumentError.length > 3) {
21507
+ const c = candidatesForArgumentError[candidatesForArgumentError.length - 1];
21508
+ const chain = chainDiagnosticMessages(undefined, Diagnostics.Failed_to_find_a_suitable_overload_for_this_call);
21484
21509
checkApplicableSignature(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain);
21485
- // related.push(argNode)
21486
- // This is not right; I want them to be siblings
21487
- // probably this is a new feature :(
21488
- // chain = chainDiagnosticMessages(chain, msg);
21510
+ }
21511
+ else {
21512
+ // const related: DiagnosticRelatedInformation[] = [];
21513
+ for (const c of candidatesForArgumentError) {
21514
+ 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);
21516
+ // related.push(argNode)
21517
+ // This is not right; I want them to be siblings
21518
+ // probably this is a new feature :(
21519
+ // chain = chainDiagnosticMessages(chain, msg);
21520
+ }
21489
21521
}
21490
21522
}
21491
21523
else if (candidateForArgumentArityError) {
0 commit comments