diff --git a/src/parser/plugins/jsx/index.ts b/src/parser/plugins/jsx/index.ts index 0ee5a3af..9b38c0a9 100644 --- a/src/parser/plugins/jsx/index.ts +++ b/src/parser/plugins/jsx/index.ts @@ -139,11 +139,11 @@ function jsxParseEmptyExpression(): void { } // Parse JSX spread child +// Does not parse the last token. function jsxParseSpreadChild(): void { expect(tt.braceL); expect(tt.ellipsis); parseExpression(); - expect(tt.braceR); } // Parses JSX expression enclosed into curly brackets. @@ -233,6 +233,7 @@ function jsxParseElementAt(): void { case tt.braceL: if (lookaheadType() === tt.ellipsis) { jsxParseSpreadChild(); + nextJSXExprToken(); } else { jsxParseExpressionContainer(); nextJSXExprToken(); diff --git a/test/jsx-test.ts b/test/jsx-test.ts index 8094069b..bb55a067 100644 --- a/test/jsx-test.ts +++ b/test/jsx-test.ts @@ -499,6 +499,17 @@ describe("transform JSX", () => { throws(() => transform("const x = <", {transforms: ["jsx"]})); }); + it("handles spread children", () => { + assertResult( + ` + const e = {...b}; + `, + `${JSX_PREFIX} + const e = React.createElement(A, {${devProps(2)}}, ...b); + `, + ); + }); + describe("with production true", () => { it("handles no props", () => { assertResult(