diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 614eaeab71f..06066e3120e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11668,52 +11668,76 @@ namespace ts { * attempt to issue more specific errors on, for example, specific object literal properties or tuple members. */ function checkTypeAssignableToAndOptionallyElaborate(source: Type, target: Type, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean { - return checkTypeRelatedToAndOptionallyElaborate(source, target, assignableRelation, errorNode, expr, headMessage, containingMessageChain); + return checkTypeRelatedToAndOptionallyElaborate(source, target, assignableRelation, errorNode, expr, headMessage, containingMessageChain, /*errorOutputContainer*/ undefined); } - function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined): boolean; - function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined, breakdown?: boolean): [Node, DiagnosticMessageChain, DiagnosticRelatedInformation[]?] | false; - function checkTypeRelatedToAndOptionallyElaborate(source: Type, target: Type, relation: Map, errorNode: Node | undefined, expr: Expression | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined, breakdown?: boolean): boolean | [Node, DiagnosticMessageChain, DiagnosticRelatedInformation[]?] { - if (isTypeRelatedTo(source, target, relation)) return breakdown ? false : true; - if (!errorNode || !elaborateError(expr, source, target, relation, headMessage)) { - return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain, undefined, breakdown); + function checkTypeRelatedToAndOptionallyElaborate( + source: Type, + target: Type, + relation: Map, + errorNode: Node | undefined, + expr: Expression | undefined, + headMessage: DiagnosticMessage | undefined, + containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, + errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } | undefined + ): boolean { + if (isTypeRelatedTo(source, target, relation)) return true; + if (!errorNode || !elaborateError(expr, source, target, relation, headMessage, errorOutputContainer)) { + return checkTypeRelatedTo(source, target, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer); } - return breakdown ? [undefined!,undefined!] as [Node, DiagnosticMessageChain] : false; + return false; } function isOrHasGenericConditional(type: Type): boolean { return !!(type.flags & TypeFlags.Conditional || (type.flags & TypeFlags.Intersection && some((type as IntersectionType).types, isOrHasGenericConditional))); } - function elaborateError(node: Expression | undefined, source: Type, target: Type, relation: Map, headMessage: DiagnosticMessage | undefined): boolean { + function elaborateError( + node: Expression | undefined, + source: Type, + target: Type, + relation: Map, + headMessage: DiagnosticMessage | undefined, + errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } | undefined + ): boolean { + // TODO: The first case probably still needs to set errorOutputContainer.error to something + // TODO: Make sure all error logging in dynamic scope sets errorOutputContainer.error instead if (!node || isOrHasGenericConditional(target)) return false; - if (!checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined) && elaborateDidYouMeanToCallOrConstruct(node, source, target, relation, headMessage)) { + if (!checkTypeRelatedTo(source, target, relation, /*errorNode*/ undefined) + && elaborateDidYouMeanToCallOrConstruct(node, source, target, relation, headMessage, errorOutputContainer)) { return true; } switch (node.kind) { case SyntaxKind.JsxExpression: case SyntaxKind.ParenthesizedExpression: - return elaborateError((node as ParenthesizedExpression | JsxExpression).expression, source, target, relation, headMessage); + return elaborateError((node as ParenthesizedExpression | JsxExpression).expression, source, target, relation, headMessage, errorOutputContainer); case SyntaxKind.BinaryExpression: switch ((node as BinaryExpression).operatorToken.kind) { case SyntaxKind.EqualsToken: case SyntaxKind.CommaToken: - return elaborateError((node as BinaryExpression).right, source, target, relation, headMessage); + return elaborateError((node as BinaryExpression).right, source, target, relation, headMessage, errorOutputContainer); } break; case SyntaxKind.ObjectLiteralExpression: - return elaborateObjectLiteral(node as ObjectLiteralExpression, source, target, relation); + return elaborateObjectLiteral(node as ObjectLiteralExpression, source, target, relation, errorOutputContainer); case SyntaxKind.ArrayLiteralExpression: - return elaborateArrayLiteral(node as ArrayLiteralExpression, source, target, relation); + return elaborateArrayLiteral(node as ArrayLiteralExpression, source, target, relation, errorOutputContainer); case SyntaxKind.JsxAttributes: - return elaborateJsxComponents(node as JsxAttributes, source, target, relation); + return elaborateJsxComponents(node as JsxAttributes, source, target, relation, errorOutputContainer); case SyntaxKind.ArrowFunction: - return elaborateArrowFunction(node as ArrowFunction, source, target, relation); + return elaborateArrowFunction(node as ArrowFunction, source, target, relation, errorOutputContainer); } return false; } - function elaborateDidYouMeanToCallOrConstruct(node: Expression, source: Type, target: Type, relation: Map, headMessage: DiagnosticMessage | undefined): boolean { + function elaborateDidYouMeanToCallOrConstruct( + node: Expression, + source: Type, + target: Type, + relation: Map, + headMessage: DiagnosticMessage | undefined, + errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } | undefined + ): boolean { const callSignatures = getSignaturesOfType(source, SignatureKind.Call); const constructSignatures = getSignaturesOfType(source, SignatureKind.Construct); for (const signatures of [constructSignatures, callSignatures]) { @@ -11721,7 +11745,7 @@ namespace ts { const returnType = getReturnTypeOfSignature(s); return !(returnType.flags & (TypeFlags.Any | TypeFlags.Never)) && checkTypeRelatedTo(returnType, target, relation, /*errorNode*/ undefined); })) { - const resultObj: { error?: Diagnostic } = {}; + const resultObj: { error?: Diagnostic } = errorOutputContainer || {}; checkTypeAssignableTo(source, target, node, headMessage, /*containingChain*/ undefined, resultObj); const diagnostic = resultObj.error!; addRelatedInfo(diagnostic, createDiagnosticForNode( @@ -11734,7 +11758,13 @@ namespace ts { return false; } - function elaborateArrowFunction(node: ArrowFunction, source: Type, target: Type, relation: Map): boolean { + function elaborateArrowFunction( + node: ArrowFunction, + source: Type, + target: Type, + relation: Map, + errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } | undefined + ): boolean { // Don't elaborate blocks if (isBlock(node.body)) { return false; @@ -11755,11 +11785,11 @@ namespace ts { const sourceReturn = getReturnTypeOfSignature(sourceSig); const targetReturn = getUnionType(map(targetSignatures, getReturnTypeOfSignature)); if (!checkTypeRelatedTo(sourceReturn, targetReturn, relation, /*errorNode*/ undefined)) { - const elaborated = returnExpression && elaborateError(returnExpression, sourceReturn, targetReturn, relation, /*headMessage*/ undefined); + const elaborated = returnExpression && elaborateError(returnExpression, sourceReturn, targetReturn, relation, /*headMessage*/ undefined, errorOutputContainer); if (elaborated) { return elaborated; } - const resultObj: { error?: Diagnostic } = {}; + const resultObj: { error?: Diagnostic } = errorOutputContainer || {}; checkTypeRelatedTo(sourceReturn, targetReturn, relation, returnExpression, /*message*/ undefined, /*chain*/ undefined, resultObj); if (resultObj.error) { if (target.symbol && length(target.symbol.declarations)) { @@ -11780,7 +11810,13 @@ namespace ts { * If that element would issue an error, we first attempt to dive into that element's inner expression and issue a more specific error by recuring into `elaborateError` * Otherwise, we issue an error on _every_ element which fail the assignability check */ - function elaborateElementwise(iterator: ElaborationIterator, source: Type, target: Type, relation: Map) { + function elaborateElementwise( + iterator: ElaborationIterator, + source: Type, + target: Type, + relation: Map, + errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } | undefined + ) { // Assignability failure - check each prop individually, and if that fails, fall back on the bad error span let reportedError = false; for (let status = iterator.next(); !status.done; status = iterator.next()) { @@ -11789,13 +11825,13 @@ namespace ts { if (!targetPropType || targetPropType.flags & TypeFlags.IndexedAccess) continue; // Don't elaborate on indexes on generic variables const sourcePropType = getIndexedAccessTypeOrUndefined(source, nameType); if (sourcePropType && !checkTypeRelatedTo(sourcePropType, targetPropType, relation, /*errorNode*/ undefined)) { - const elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation, /*headMessage*/ undefined); + const elaborated = next && elaborateError(next, sourcePropType, targetPropType, relation, /*headMessage*/ undefined, errorOutputContainer); if (elaborated) { reportedError = true; } else { // Issue error on the prop itself, since the prop couldn't elaborate the error - const resultObj: { error?: Diagnostic } = {}; + const resultObj: { error?: Diagnostic } = errorOutputContainer || {}; // Use the expression type, if available const specificSource = next ? checkExpressionForMutableLocation(next, CheckMode.Normal, sourcePropType) : sourcePropType; const result = checkTypeRelatedTo(specificSource, targetPropType, relation, prop, errorMessage, /*containingChain*/ undefined, resultObj); @@ -11887,8 +11923,14 @@ namespace ts { return filter(children, i => !isJsxText(i) || !i.containsOnlyTriviaWhiteSpaces); } - function elaborateJsxComponents(node: JsxAttributes, source: Type, target: Type, relation: Map) { - let result = elaborateElementwise(generateJsxAttributes(node), source, target, relation); + function elaborateJsxComponents( + node: JsxAttributes, + source: Type, + target: Type, + relation: Map, + errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } | undefined + ) { + let result = elaborateElementwise(generateJsxAttributes(node), source, target, relation, errorOutputContainer); let invalidTextDiagnostic: DiagnosticMessage | undefined; if (isJsxOpeningElement(node.parent) && isJsxElement(node.parent.parent)) { const containingElement = node.parent.parent; @@ -11906,17 +11948,21 @@ namespace ts { if (moreThanOneRealChildren) { if (arrayLikeTargetParts !== neverType) { const realSource = createTupleType(checkJsxChildren(containingElement, CheckMode.Normal)); - result = elaborateElementwise(generateJsxChildren(containingElement, getInvalidTextualChildDiagnostic), realSource, arrayLikeTargetParts, relation) || result; + const children = generateJsxChildren(containingElement, getInvalidTextualChildDiagnostic) + result = elaborateElementwise(children, realSource, arrayLikeTargetParts, relation, errorOutputContainer) || result; } else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) { // arity mismatch result = true; - error( + const diag = error( containingElement.openingElement.tagName, Diagnostics.This_JSX_tag_s_0_prop_expects_a_single_child_of_type_1_but_multiple_children_were_provided, childrenPropName, typeToString(childrenTargetType) ); + if (errorOutputContainer && errorOutputContainer.skipLogging) { + errorOutputContainer.error = diag; + } } } else { @@ -11928,19 +11974,23 @@ namespace ts { (function*() { yield elem; })(), source, target, - relation + relation, + errorOutputContainer ) || result; } } else if (!isTypeRelatedTo(getIndexedAccessType(source, childrenNameType), childrenTargetType, relation)) { // arity mismatch result = true; - error( + const diag = error( containingElement.openingElement.tagName, Diagnostics.This_JSX_tag_s_0_prop_expects_type_1_which_requires_multiple_children_but_only_a_single_child_was_provided, childrenPropName, typeToString(childrenTargetType) ); + if (errorOutputContainer && errorOutputContainer.skipLogging) { + errorOutputContainer.error = diag; + } } } } @@ -11972,15 +12022,21 @@ namespace ts { } } - function elaborateArrayLiteral(node: ArrayLiteralExpression, source: Type, target: Type, relation: Map) { + function elaborateArrayLiteral( + node: ArrayLiteralExpression, + source: Type, + target: Type, + relation: Map, + errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } | undefined + ) { if (target.flags & TypeFlags.Primitive) return false; if (isTupleLikeType(source)) { - return elaborateElementwise(generateLimitedTupleElements(node, target), source, target, relation); + return elaborateElementwise(generateLimitedTupleElements(node, target), source, target, relation, errorOutputContainer); } // recreate a tuple from the elements, if possible const tupleizedType = checkArrayLiteral(node, CheckMode.Contextual, /*forceTuple*/ true); if (isTupleLikeType(tupleizedType)) { - return elaborateElementwise(generateLimitedTupleElements(node, target), tupleizedType, target, relation); + return elaborateElementwise(generateLimitedTupleElements(node, target), tupleizedType, target, relation, errorOutputContainer); } return false; } @@ -12009,9 +12065,15 @@ namespace ts { } } - function elaborateObjectLiteral(node: ObjectLiteralExpression, source: Type, target: Type, relation: Map) { + function elaborateObjectLiteral( + node: ObjectLiteralExpression, + source: Type, + target: Type, + relation: Map, + errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } | undefined + ) { if (target.flags & TypeFlags.Primitive) return false; - return elaborateElementwise(generateObjectLiteralElements(node), source, target, relation); + return elaborateElementwise(generateObjectLiteralElements(node), source, target, relation, errorOutputContainer); } /** @@ -12343,25 +12405,6 @@ namespace ts { return getObjectFlags(source) & ObjectFlags.JsxAttributes && !isUnhyphenatedJsxName(sourceProp.escapedName); } - function checkTypeRelatedTo( - source: Type, - target: Type, - relation: Map, - errorNode: Node | undefined, - headMessage?: DiagnosticMessage, - containingMessageChain?: () => DiagnosticMessageChain | undefined, - errorOutputContainer?: { error?: Diagnostic }, - ): boolean; - function checkTypeRelatedTo( - source: Type, - target: Type, - relation: Map, - errorNode: Node | undefined, - headMessage?: DiagnosticMessage, - containingMessageChain?: () => DiagnosticMessageChain | undefined, - errorOutputContainer?: { error?: Diagnostic }, - breakdown?: boolean - ): false | [Node, DiagnosticMessageChain, DiagnosticRelatedInformation[]?]; /** * Checks if 'source' is related to 'target' (e.g.: is a assignable to). * @param source The left-hand-side of the relation. @@ -12371,6 +12414,7 @@ namespace ts { * @param errorNode The suggested node upon which all errors will be reported, if defined. This may or may not be the actual node used. * @param headMessage If the error chain should be prepended by a head message, then headMessage will be used. * @param containingMessageChain A chain of errors to prepend any new errors found. + * @param errorOutputContainer Return the diagnostic. Do not log if 'skipLogging' is truthy. */ function checkTypeRelatedTo( source: Type, @@ -12379,9 +12423,8 @@ namespace ts { errorNode: Node | undefined, headMessage?: DiagnosticMessage, containingMessageChain?: () => DiagnosticMessageChain | undefined, - errorOutputContainer?: { error?: Diagnostic }, - breakdown?: boolean - ): boolean | [Node, DiagnosticMessageChain, DiagnosticRelatedInformation[]?] { + errorOutputContainer?: { error?: Diagnostic, skipLogging?: boolean }, + ): boolean { let errorInfo: DiagnosticMessageChain | undefined; let relatedInfo: [DiagnosticRelatedInformation, ...DiagnosticRelatedInformation[]] | undefined; let maybeKeys: string[]; @@ -12397,7 +12440,10 @@ namespace ts { const result = isRelatedTo(source, target, /*reportErrors*/ !!errorNode, headMessage); if (overflow) { - error(errorNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target)); + const diag = error(errorNode, Diagnostics.Excessive_stack_depth_comparing_types_0_and_1, typeToString(source), typeToString(target)); + if (errorOutputContainer) { + errorOutputContainer.error = diag; + } } else if (errorInfo) { if (containingMessageChain) { @@ -12420,9 +12466,6 @@ namespace ts { } } } - if (breakdown) { - return [errorNode!, errorInfo, relatedInfo ? [...(relatedInformation || []), ...relatedInfo]: relatedInformation]; - } const diag = createDiagnosticForNodeFromMessageChain(errorNode!, errorInfo, relatedInformation); if (relatedInfo) { addRelatedInfo(diag, ...relatedInfo); @@ -12430,11 +12473,12 @@ namespace ts { if (errorOutputContainer) { errorOutputContainer.error = diag; } - diagnostics.add(diag); // TODO: GH#18217 + if (!errorOutputContainer || !errorOutputContainer.skipLogging) { + diagnostics.add(diag); + } } - if (breakdown) { - Debug.assert(result === Ternary.False ? !errorNode : true, "missed opportunity to interact with error."); - return result === Ternary.False ? [undefined!, undefined!] as [Node, DiagnosticMessageChain] : false; + if (errorNode && errorOutputContainer && errorOutputContainer.skipLogging && result === Ternary.False) { + Debug.assert(!!errorOutputContainer.error, "missed opportunity to interact with error."); } return result !== Ternary.False; @@ -21127,13 +21171,14 @@ namespace ts { checkMode: CheckMode, reportErrors: boolean, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, + errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } ) { // Stateless function components can have maximum of three arguments: "props", "context", and "updater". // However "context" and "updater" are implicit and can't be specify by users. Only the first parameter, props, // can be specified by users through attributes property. const paramType = getEffectiveFirstArgumentForJsxSignature(signature, node); const attributesType = checkExpressionWithContextualType(node.attributes, paramType, /*inferenceContext*/ undefined, checkMode); - return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes, undefined, containingMessageChain, /*breakdown*/ true); + return checkTypeRelatedToAndOptionallyElaborate(attributesType, paramType, relation, reportErrors ? node.tagName : undefined, node.attributes, undefined, containingMessageChain, errorOutputContainer); } function getSignatureApplicabilityError( @@ -21145,8 +21190,19 @@ namespace ts { reportErrors: boolean, containingMessageChain: (() => DiagnosticMessageChain | undefined) | undefined, ) { + + const errorOutputContainer: { error?: Diagnostic, skipLogging?: boolean } = { error: undefined, skipLogging: true }; if (isJsxOpeningLikeElement(node)) { - return checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain); + const r = checkApplicableSignatureForJsxOpeningLikeElement(node, signature, relation, checkMode, reportErrors, containingMessageChain, errorOutputContainer); + if (!r) { + if (reportErrors) { + Debug.assert(!!errorOutputContainer.error, "has error 0"); + return errorOutputContainer.error; + } + else { + return true; + } + } } const thisType = getThisTypeOfSignature(signature); if (thisType && thisType !== voidType && node.kind !== SyntaxKind.NewExpression) { @@ -21157,9 +21213,15 @@ namespace ts { const thisArgumentType = thisArgumentNode ? checkExpression(thisArgumentNode) : voidType; const errorNode = reportErrors ? (thisArgumentNode || node) : undefined; const headMessage = Diagnostics.The_this_context_of_type_0_is_not_assignable_to_method_s_this_of_type_1; - const r = checkTypeRelatedTo(thisArgumentType, thisType, relation, errorNode, headMessage, containingMessageChain, undefined, /*breakdown*/ true); - if (r) { - return r; + const r = checkTypeRelatedTo(thisArgumentType, thisType, relation, errorNode, headMessage, containingMessageChain, errorOutputContainer); + if (!r) { + if (reportErrors) { + Debug.assert(!!errorOutputContainer.error, "has error 1"); // CLEAR + return errorOutputContainer.error; + } + else { + return true; + } } } const headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1; @@ -21174,16 +21236,31 @@ namespace ts { // we obtain the regular type of any object literal arguments because we may not have inferred complete // parameter types yet and therefore excess property checks may yield false positives (see #17041). const checkArgType = checkMode & CheckMode.SkipContextSensitive ? getRegularTypeOfObjectLiteral(argType) : argType; - const r = checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage, containingMessageChain, /*breakdown*/ true); - if (r) { - return r; + const r = checkTypeRelatedToAndOptionallyElaborate(checkArgType, paramType, relation, reportErrors ? arg : undefined, arg, headMessage, containingMessageChain, errorOutputContainer); + if (!r) { + if (reportErrors) { + Debug.assert(!!errorOutputContainer.error, "has error 2"); // CLEAR + return errorOutputContainer.error; + } + else { + return true; + } } } } if (restType) { const spreadType = getSpreadArgumentType(args, argCount, args.length, restType, /*context*/ undefined); const errorNode = reportErrors ? argCount < args.length ? args[argCount] : node : undefined; - return checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, undefined, undefined, /*breakdown*/ true); + const r = checkTypeRelatedTo(spreadType, restType, relation, errorNode, headMessage, undefined, errorOutputContainer); + if (!r) { + if (reportErrors) { + Debug.assert(!!errorOutputContainer.error, "has error 3"); // CLEAR + return errorOutputContainer.error; + } + else { + return true; + } + } } return undefined; } @@ -21520,10 +21597,13 @@ namespace ts { chain = chainDiagnosticMessages(chain, Diagnostics.The_last_overload_gave_the_following_error); chain = chainDiagnosticMessages(chain, Diagnostics.No_suitable_overload_for_this_call); } - const r = getSignatureApplicabilityError(node, args, last, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain); - Debug.assert(!!r && !!r[0], "No error for last signature"); - if (r) { - diagnostics.add(createDiagnosticForNodeFromMessageChain(...r)); + const d = getSignatureApplicabilityError(node, args, last, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain); + Debug.assert(!!d, "No error for last signature"); + if (d) { + Debug.assert(d !== true); + // if elaboration already displayed the error, don't do anything extra + // note that we could do this always here, but getSignatureApplicabilityError is currently not configured to do that + diagnostics.add(d as Diagnostic); } } else { @@ -21532,10 +21612,11 @@ namespace ts { for (const c of candidatesForArgumentError) { i++; const chain = chainDiagnosticMessages(undefined, Diagnostics.Overload_0_of_1_2_gave_the_following_error, i, candidates.length, signatureToString(c)); - const r = getSignatureApplicabilityError(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain); - Debug.assert(!!r && !!r[0], "No error for signature (1)"); - if (r) { - related.push(createDiagnosticForNodeFromMessageChain(...r)); + const d = getSignatureApplicabilityError(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain); + Debug.assert(!!d, "No error for signature (1)"); + if (d) { + Debug.assert(d !== true); + related.push(d as Diagnostic); } } diagnostics.add(createDiagnosticForNodeFromMessageChain(node, chainDiagnosticMessages(undefined, Diagnostics.No_suitable_overload_for_this_call), related)); diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt index 9101537a6e9..9a5486fa8bf 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt @@ -1,8 +1,7 @@ -tests/cases/conformance/jsx/file.tsx(48,13): error TS2322: Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. - Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. -tests/cases/conformance/jsx/file.tsx(54,51): error TS2322: Type 'number' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(55,68): error TS2322: Type 'true' is not assignable to type 'string'. -tests/cases/conformance/jsx/file.tsx(56,24): error TS2322: Type 'true' is not assignable to type 'string'. +tests/cases/conformance/jsx/file.tsx(48,12): error TS2755: No suitable overload for this call. +tests/cases/conformance/jsx/file.tsx(54,12): error TS2755: No suitable overload for this call. +tests/cases/conformance/jsx/file.tsx(55,12): error TS2755: No suitable overload for this call. +tests/cases/conformance/jsx/file.tsx(56,12): error TS2755: No suitable overload for this call. ==== tests/cases/conformance/jsx/file.tsx (4 errors) ==== @@ -54,23 +53,39 @@ tests/cases/conformance/jsx/file.tsx(56,24): error TS2322: Type 'true' is not as // Error const b0 = {}}>GO; // extra property; - ~~~~~~~~~~ -!!! error TS2322: Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. -!!! error TS2322: Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2755: No suitable overload for this call. +!!! related TS2757 tests/cases/conformance/jsx/file.tsx:48:13: Overload 1 of 3, '(buttonProps: ButtonProps): Element', gave the following error. + Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. + Property 'to' does not exist on type 'IntrinsicAttributes & ButtonProps'. +!!! related TS2757 tests/cases/conformance/jsx/file.tsx:48:13: Overload 2 of 3, '(linkProps: LinkProps): Element', gave the following error. + Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. + Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. +!!! related TS2757 tests/cases/conformance/jsx/file.tsx:48:13: Overload 3 of 3, '(hyphenProps: HyphenProps): Element', gave the following error. + Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. const b1 = {}} {...obj0}>Hello world; // extra property; const b2 = ; // extra property const b3 = {}}} />; // extra property const b4 = ; // Should error because Incorrect type; but attributes are any so everything is allowed const b5 = ; // Spread retain method declaration (see GitHub #13365), so now there is an extra attributes const b6 = ; // incorrect type for optional attribute - ~~~~~~~~ -!!! error TS2322: Type 'number' is not assignable to type 'string'. -!!! related TS6500 tests/cases/conformance/jsx/file.tsx:4:5: The expected type comes from property 'children' which is declared here on type 'IntrinsicAttributes & HyphenProps' + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2755: No suitable overload for this call. +!!! related TS2322 tests/cases/conformance/jsx/file.tsx:54:51: Type 'number' is not assignable to type 'string'. +!!! related TS2322 tests/cases/conformance/jsx/file.tsx:54:51: Type 'number' is not assignable to type 'string'. +!!! related TS2322 tests/cases/conformance/jsx/file.tsx:54:51: Type 'number' is not assignable to type 'string'. const b7 = ; // incorrect type for optional attribute - ~~~~~~~~~ -!!! error TS2322: Type 'true' is not assignable to type 'string'. -!!! related TS6500 tests/cases/conformance/jsx/file.tsx:5:5: The expected type comes from property 'className' which is declared here on type 'IntrinsicAttributes & HyphenProps' + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2755: No suitable overload for this call. +!!! related TS2322 tests/cases/conformance/jsx/file.tsx:55:68: Type 'true' is not assignable to type 'string'. +!!! related TS2322 tests/cases/conformance/jsx/file.tsx:55:68: Type 'true' is not assignable to type 'string'. +!!! related TS2322 tests/cases/conformance/jsx/file.tsx:55:68: Type 'true' is not assignable to type 'string'. const b8 = ; // incorrect type for specified hyphanated name - ~~~~~~~~~~~ -!!! error TS2322: Type 'true' is not assignable to type 'string'. -!!! related TS6500 tests/cases/conformance/jsx/file.tsx:17:5: The expected type comes from property 'data-format' which is declared here on type 'IntrinsicAttributes & HyphenProps' \ No newline at end of file + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2755: No suitable overload for this call. +!!! related TS2757 tests/cases/conformance/jsx/file.tsx:56:13: Overload 1 of 3, '(buttonProps: ButtonProps): Element', gave the following error. + Property 'onClick' is missing in type '{ data-format: true; }' but required in type 'ButtonProps'. +!!! related TS2757 tests/cases/conformance/jsx/file.tsx:56:13: Overload 2 of 3, '(linkProps: LinkProps): Element', gave the following error. + Property 'to' is missing in type '{ data-format: true; }' but required in type 'LinkProps'. +!!! related TS2322 tests/cases/conformance/jsx/file.tsx:56:24: Type 'true' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.types b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.types index d9b40dad94f..6a9b770ef48 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.types +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.types @@ -113,9 +113,9 @@ const b0 = {}}>GO; // ex >{}}>GO : JSX.Element >MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } >to : string ->onClick : (e: any) => void ->(e)=>{} : (e: any) => void ->e : any +>onClick : (e: React.MouseEvent) => void +>(e)=>{} : (e: React.MouseEvent) => void +>e : React.MouseEvent >MainButton : { (buttonProps: ButtonProps): JSX.Element; (linkProps: LinkProps): JSX.Element; (hyphenProps: HyphenProps): JSX.Element; } const b1 = {}} {...obj0}>Hello world; // extra property;