diff --git a/tsc/internal/parser/parser.go b/tsc/internal/parser/parser.go index f54b4bcebbdf3..1d149790b7565 100644 --- a/tsc/internal/parser/parser.go +++ b/tsc/internal/parser/parser.go @@ -5093,7 +5093,9 @@ func (p *Parser) parseJsxAttributeValue() *ast.Expression { return p.parseJsxExpression( /*inExpressionContext*/ true) } if p.token == ast.KindLessThanToken { - return p.parseJsxElementOrSelfClosingElementOrFragment(true /*inExpressionContext*/, -1, nil, false) + // An attribute value must be a single JsxAttributeValue, so don't allow the sibling-element + // recovery to wrap it in a synthetic binary expression. + return p.parseJsxElementOrSelfClosingElementOrFragment(true /*inExpressionContext*/, -1 /*topInvalidNodePosition*/, nil /*openingTag*/, true /*mustBeUnary*/) } p.parseErrorAtCurrentToken(diagnostics.X_or_JSX_element_expected) } diff --git a/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react).errors.txt b/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react).errors.txt new file mode 100644 index 0000000000000..8d85ee0d7508e --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react).errors.txt @@ -0,0 +1,20 @@ +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,11): error TS2657: JSX expressions must have one parent element. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,29): error TS1003: Identifier expected. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,39): error TS1109: Expression expected. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,40): error TS1109: Expression expected. + + +==== jsxAttributeInitializerMultipleElementsNoCrash.tsx (4 errors) ==== + declare namespace JSX { interface IntrinsicElements { [x: string]: any } } + declare const React: any; + + const a =
/>; + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2657: JSX expressions must have one parent element. + ~ +!!! error TS1003: Identifier expected. + ~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1109: Expression expected. + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react).js b/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react).js new file mode 100644 index 0000000000000..1781372e99826 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react).js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/jsxAttributeInitializerMultipleElementsNoCrash.tsx] //// + +//// [jsxAttributeInitializerMultipleElementsNoCrash.tsx] +declare namespace JSX { interface IntrinsicElements { [x: string]: any } } +declare const React: any; + +const a = />; + + +//// [jsxAttributeInitializerMultipleElementsNoCrash.js] +"use strict"; +const a = (React.createElement("div", { attr: React.createElement("span", null) }), React.createElement("span", null)) / > ; diff --git a/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react-jsx).errors.txt b/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react-jsx).errors.txt new file mode 100644 index 0000000000000..6a8c9ca6381fe --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react-jsx).errors.txt @@ -0,0 +1,32 @@ +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,11): error TS2875: This JSX tag requires the module path 'react/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,11): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,11): error TS2657: JSX expressions must have one parent element. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,21): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,29): error TS1003: Identifier expected. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,29): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,39): error TS1109: Expression expected. +jsxAttributeInitializerMultipleElementsNoCrash.tsx(4,40): error TS1109: Expression expected. + + +==== jsxAttributeInitializerMultipleElementsNoCrash.tsx (8 errors) ==== + declare namespace JSX { interface IntrinsicElements { [x: string]: any } } + declare const React: any; + + const a = />; + ~~~~~~~~~~~~~~~~~~ +!!! error TS2875: This JSX tag requires the module path 'react/jsx-runtime' to exist, but none could be found. Make sure you have types for the appropriate package installed. + ~~~~~~~~~~~~~~~~~~ +!!! error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. + ~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2657: JSX expressions must have one parent element. + ~~~~~~~~ +!!! error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. + ~ +!!! error TS1003: Identifier expected. + ~~~~~~~~ +!!! error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. + ~ +!!! error TS1109: Expression expected. + ~ +!!! error TS1109: Expression expected. + \ No newline at end of file diff --git a/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react-jsx).js b/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react-jsx).js new file mode 100644 index 0000000000000..0db391e644a76 --- /dev/null +++ b/tsc/testdata/baselines/reference/compiler/jsxAttributeInitializerMultipleElementsNoCrash(jsx=react-jsx).js @@ -0,0 +1,12 @@ +//// [tests/cases/compiler/jsxAttributeInitializerMultipleElementsNoCrash.tsx] //// + +//// [jsxAttributeInitializerMultipleElementsNoCrash.tsx] +declare namespace JSX { interface IntrinsicElements { [x: string]: any } } +declare const React: any; + +const a = />; + + +//// [jsxAttributeInitializerMultipleElementsNoCrash.js] +import { jsx as _jsx } from "react/jsx-runtime"; +const a = (_jsx("div", { attr: _jsx("span", {}) }), _jsx("span", {})) / > ; diff --git a/tsc/testdata/baselines/reference/compiler/jsxAttributeValueBinaryExpression.errors.txt b/tsc/testdata/baselines/reference/compiler/jsxAttributeValueBinaryExpression.errors.txt index c6524a1a9811b..2eccf0021f44e 100644 --- a/tsc/testdata/baselines/reference/compiler/jsxAttributeValueBinaryExpression.errors.txt +++ b/tsc/testdata/baselines/reference/compiler/jsxAttributeValueBinaryExpression.errors.txt @@ -1,17 +1,26 @@ +jsxAttributeValueBinaryExpression.tsx(1,1): error TS2657: JSX expressions must have one parent element. jsxAttributeValueBinaryExpression.tsx(1,2): error TS2304: Cannot find name 'X'. jsxAttributeValueBinaryExpression.tsx(1,6): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. -jsxAttributeValueBinaryExpression.tsx(1,6): error TS2657: JSX expressions must have one parent element. +jsxAttributeValueBinaryExpression.tsx(1,10): error TS1003: Identifier expected. jsxAttributeValueBinaryExpression.tsx(1,10): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists. +jsxAttributeValueBinaryExpression.tsx(1,16): error TS1109: Expression expected. +jsxAttributeValueBinaryExpression.tsx(1,17): error TS1109: Expression expected. -==== jsxAttributeValueBinaryExpression.tsx (4 errors) ==== +==== jsxAttributeValueBinaryExpression.tsx (7 errors) ====