diff --git a/crates/swc/tests/fixture/issues-2xxx/2037/case1/output/index.js b/crates/swc/tests/fixture/issues-2xxx/2037/case1/output/index.js
index a3dd991f4775..2981991490b9 100644
--- a/crates/swc/tests/fixture/issues-2xxx/2037/case1/output/index.js
+++ b/crates/swc/tests/fixture/issues-2xxx/2037/case1/output/index.js
@@ -1,3 +1,6 @@
var A = function() {
- return /*#__PURE__*/ React.createElement("div", null);
+ return /*#__PURE__*/ React.createElement.apply(React, [
+ "div",
+ null
+ ]);
};
diff --git a/crates/swc/tests/tsc-references/inlineJsxFactoryDeclarationsLocalTypes.1.normal.js b/crates/swc/tests/tsc-references/inlineJsxFactoryDeclarationsLocalTypes.1.normal.js
index 630c51b0e2cf..71ab051f7c91 100644
--- a/crates/swc/tests/tsc-references/inlineJsxFactoryDeclarationsLocalTypes.1.normal.js
+++ b/crates/swc/tests/tsc-references/inlineJsxFactoryDeclarationsLocalTypes.1.normal.js
@@ -3,22 +3,106 @@ export { };
//// [renderer2.d.ts]
export { };
//// [component.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 4 | export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) =>
{props.x} + {props.y} = {props.x + props.y}{...this.props.children}
;
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 12 | {...this.props.children}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+/** @jsx predom */ import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
+import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
+var _this = this;
+import { predom } from "./renderer2";
+export var MySFC = function(props) {
+ return /*#__PURE__*/ predom.apply(void 0, [
+ "p",
+ null,
+ props.x,
+ " + ",
+ props.y,
+ " = ",
+ props.x + props.y
+ ].concat(_to_consumable_array(_this.props.children)));
+};
+export var MyClass = /*#__PURE__*/ function() {
+ "use strict";
+ function MyClass(props) {
+ _class_call_check(this, MyClass);
+ this.props = props;
+ }
+ var _proto = MyClass.prototype;
+ _proto.render = function render() {
+ return /*#__PURE__*/ predom.apply(void 0, [
+ "p",
+ null,
+ this.props.x,
+ " + ",
+ this.props.y,
+ " = ",
+ this.props.x + this.props.y
+ ].concat(_to_consumable_array(this.props.children)));
+ };
+ return MyClass;
+}();
+export var tree = /*#__PURE__*/ predom(MySFC, {
+ x: 1,
+ y: 2
+}, /*#__PURE__*/ predom(MyClass, {
+ x: 3,
+ y: 4
+}), /*#__PURE__*/ predom(MyClass, {
+ x: 5,
+ y: 6
+}));
+export default /*#__PURE__*/ predom("h", null);
//// [index.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 13 | return {this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}
;
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+/** @jsx dom */ import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
+import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
+import { dom } from "./renderer";
+import prerendered, { MySFC, MyClass, tree } from "./component";
+var elem = prerendered;
+elem = /*#__PURE__*/ dom("h", null); // Expect assignability error here
+var DOMSFC = function(props) {
+ return /*#__PURE__*/ dom("p", null, props.x, " + ", props.y, " = ", props.x + props.y, props.children);
+};
+var DOMClass = /*#__PURE__*/ function() {
+ "use strict";
+ function DOMClass(props) {
+ _class_call_check(this, DOMClass);
+ this.props = props;
+ }
+ var _proto = DOMClass.prototype;
+ _proto.render = function render() {
+ return /*#__PURE__*/ dom.apply(void 0, [
+ "p",
+ null,
+ this.props.x,
+ " + ",
+ this.props.y,
+ " = ",
+ this.props.x + this.props.y
+ ].concat(_to_consumable_array(this.props.children)));
+ };
+ return DOMClass;
+}();
+// Should work, everything is a DOM element
+var _tree = /*#__PURE__*/ dom(DOMSFC, {
+ x: 1,
+ y: 2
+}, /*#__PURE__*/ dom(DOMClass, {
+ x: 3,
+ y: 4
+}), /*#__PURE__*/ dom(DOMClass, {
+ x: 5,
+ y: 6
+}));
+// Should fail, no dom elements
+var _brokenTree = /*#__PURE__*/ dom(MySFC, {
+ x: 1,
+ y: 2
+}, /*#__PURE__*/ dom(MyClass, {
+ x: 3,
+ y: 4
+}), /*#__PURE__*/ dom(MyClass, {
+ x: 5,
+ y: 6
+}));
+// Should fail, nondom isn't allowed as children of dom
+var _brokenTree2 = /*#__PURE__*/ dom(DOMSFC, {
+ x: 1,
+ y: 2
+}, tree, tree);
diff --git a/crates/swc/tests/tsc-references/inlineJsxFactoryDeclarationsLocalTypes.2.minified.js b/crates/swc/tests/tsc-references/inlineJsxFactoryDeclarationsLocalTypes.2.minified.js
index 630c51b0e2cf..cb4c7cd86638 100644
--- a/crates/swc/tests/tsc-references/inlineJsxFactoryDeclarationsLocalTypes.2.minified.js
+++ b/crates/swc/tests/tsc-references/inlineJsxFactoryDeclarationsLocalTypes.2.minified.js
@@ -3,22 +3,51 @@ export { };
//// [renderer2.d.ts]
export { };
//// [component.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 4 | export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{...this.props.children}
;
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 12 | {...this.props.children}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
+import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
+var _this = this;
+import { predom } from "./renderer2";
+export var MySFC = function(props) {
+ return predom.apply(void 0, [
+ "p",
+ null,
+ props.x,
+ " + ",
+ props.y,
+ " = ",
+ props.x + props.y
+ ].concat(_to_consumable_array(_this.props.children)));
+};
+export var MyClass = function() {
+ "use strict";
+ function MyClass(props) {
+ _class_call_check(this, MyClass), this.props = props;
+ }
+ return MyClass.prototype.render = function() {
+ return predom.apply(void 0, [
+ "p",
+ null,
+ this.props.x,
+ " + ",
+ this.props.y,
+ " = ",
+ this.props.x + this.props.y
+ ].concat(_to_consumable_array(this.props.children)));
+ }, MyClass;
+}();
+export var tree = predom(MySFC, {
+ x: 1,
+ y: 2
+}, predom(MyClass, {
+ x: 3,
+ y: 4
+}), predom(MyClass, {
+ x: 5,
+ y: 6
+}));
+export default predom("h", null);
//// [index.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 13 | return {this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}
;
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+import _class_call_check from "@swc/helpers/src/_class_call_check.mjs";
+import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
+import { dom } from "./renderer";
+import prerendered, { MySFC, MyClass, tree } from "./component";
diff --git a/crates/swc/tests/tsc-references/tsxSpreadChildren.1.normal.js b/crates/swc/tests/tsc-references/tsxSpreadChildren.1.normal.js
index b019991955f9..b44b53a6deb2 100644
--- a/crates/swc/tests/tsc-references/tsxSpreadChildren.1.normal.js
+++ b/crates/swc/tests/tsc-references/tsxSpreadChildren.1.normal.js
@@ -1,7 +1,20 @@
//// [tsxSpreadChildren.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 22 | {...todos.map(todo => )}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+import _extends from "@swc/helpers/src/_extends.mjs";
+import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
+function Todo(prop) {
+ return /*#__PURE__*/ React.createElement("div", null, prop.key.toString() + prop.todo);
+}
+function TodoList(param) {
+ var todos = param.todos;
+ return /*#__PURE__*/ React.createElement.apply(React, [
+ "div",
+ null
+ ].concat(_to_consumable_array(todos.map(function(todo) {
+ return /*#__PURE__*/ React.createElement(Todo, {
+ key: todo.id,
+ todo: todo.todo
+ });
+ }))));
+}
+var x;
+/*#__PURE__*/ React.createElement(TodoList, _extends({}, x));
diff --git a/crates/swc/tests/tsc-references/tsxSpreadChildren.2.minified.js b/crates/swc/tests/tsc-references/tsxSpreadChildren.2.minified.js
index b019991955f9..9febbcac7e62 100644
--- a/crates/swc/tests/tsc-references/tsxSpreadChildren.2.minified.js
+++ b/crates/swc/tests/tsc-references/tsxSpreadChildren.2.minified.js
@@ -1,7 +1,5 @@
//// [tsxSpreadChildren.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 22 | {...todos.map(todo => )}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+var x;
+import _extends from "@swc/helpers/src/_extends.mjs";
+import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
+_extends({}, x);
diff --git a/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es2015).1.normal.js b/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es2015).1.normal.js
index 49c09e75c679..ec30394b2e5d 100644
--- a/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es2015).1.normal.js
+++ b/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es2015).1.normal.js
@@ -1,13 +1,20 @@
//// [tsxSpreadChildrenInvalidType.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 21 | {...}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 27 | {...( as any)}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+import _extends from "@swc/helpers/src/_extends.mjs";
+function Todo(prop) {
+ return /*#__PURE__*/ React.createElement("div", null, prop.key.toString() + prop.todo);
+}
+function TodoList({ todos }) {
+ return /*#__PURE__*/ React.createElement("div", null, .../*#__PURE__*/ React.createElement(Todo, {
+ key: todos[0].id,
+ todo: todos[0].todo
+ }));
+}
+function TodoListNoError({ todos }) {
+ // any is not checked
+ return /*#__PURE__*/ React.createElement("div", null, .../*#__PURE__*/ React.createElement(Todo, {
+ key: todos[0].id,
+ todo: todos[0].todo
+ }));
+}
+let x;
+/*#__PURE__*/ React.createElement(TodoList, _extends({}, x));
diff --git a/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es2015).2.minified.js b/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es2015).2.minified.js
index 49c09e75c679..47b53e474548 100644
--- a/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es2015).2.minified.js
+++ b/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es2015).2.minified.js
@@ -1,13 +1,4 @@
//// [tsxSpreadChildrenInvalidType.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 21 | {...}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 27 | {...( as any)}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+let x;
+import _extends from "@swc/helpers/src/_extends.mjs";
+_extends({}, x);
diff --git a/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es5).1.normal.js b/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es5).1.normal.js
index 49c09e75c679..60479af70f58 100644
--- a/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es5).1.normal.js
+++ b/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es5).1.normal.js
@@ -1,13 +1,29 @@
//// [tsxSpreadChildrenInvalidType.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 21 | {...}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 27 | {...( as any)}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+import _extends from "@swc/helpers/src/_extends.mjs";
+import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
+function Todo(prop) {
+ return /*#__PURE__*/ React.createElement("div", null, prop.key.toString() + prop.todo);
+}
+function TodoList(param) {
+ var todos = param.todos;
+ return /*#__PURE__*/ React.createElement.apply(React, [
+ "div",
+ null
+ ].concat(_to_consumable_array(/*#__PURE__*/ React.createElement(Todo, {
+ key: todos[0].id,
+ todo: todos[0].todo
+ }))));
+}
+function TodoListNoError(param) {
+ var todos = param.todos;
+ // any is not checked
+ return /*#__PURE__*/ React.createElement.apply(React, [
+ "div",
+ null
+ ].concat(_to_consumable_array(/*#__PURE__*/ React.createElement(Todo, {
+ key: todos[0].id,
+ todo: todos[0].todo
+ }))));
+}
+var x;
+/*#__PURE__*/ React.createElement(TodoList, _extends({}, x));
diff --git a/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es5).2.minified.js b/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es5).2.minified.js
index 49c09e75c679..fd4b63d90b27 100644
--- a/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es5).2.minified.js
+++ b/crates/swc/tests/tsc-references/tsxSpreadChildrenInvalidType(target=es5).2.minified.js
@@ -1,13 +1,5 @@
//// [tsxSpreadChildrenInvalidType.tsx]
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 21 | {...}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
-//!
-//! x Spread children are not supported in React.
-//! ,----
-//! 27 | {...( as any)}
-//! : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-//! `----
+var x;
+import _extends from "@swc/helpers/src/_extends.mjs";
+import _to_consumable_array from "@swc/helpers/src/_to_consumable_array.mjs";
+_extends({}, x);
diff --git a/crates/swc_ecma_transforms_react/src/jsx/mod.rs b/crates/swc_ecma_transforms_react/src/jsx/mod.rs
index 5d2152b8190f..11b9135863f6 100644
--- a/crates/swc_ecma_transforms_react/src/jsx/mod.rs
+++ b/crates/swc_ecma_transforms_react/src/jsx/mod.rs
@@ -769,14 +769,10 @@ where
}) => return None,
JSXElementChild::JSXElement(el) => self.jsx_elem_to_expr(*el).as_arg(),
JSXElementChild::JSXFragment(el) => self.jsx_frag_to_expr(el).as_arg(),
- JSXElementChild::JSXSpreadChild(JSXSpreadChild { span, .. }) => {
- HANDLER.with(|handler| {
- handler
- .struct_span_err(span, "Spread children are not supported in React.")
- .emit();
- });
- return None;
- }
+ JSXElementChild::JSXSpreadChild(JSXSpreadChild { span, expr, .. }) => ExprOrSpread {
+ spread: Some(span),
+ expr,
+ },
})
}
diff --git a/crates/swc_ecma_transforms_react/tests/jsx/fixture/vercel/3/input.js b/crates/swc_ecma_transforms_react/tests/jsx/fixture/3/input.js
similarity index 100%
rename from crates/swc_ecma_transforms_react/tests/jsx/fixture/vercel/3/input.js
rename to crates/swc_ecma_transforms_react/tests/jsx/fixture/3/input.js
diff --git a/crates/swc_ecma_transforms_react/tests/jsx/fixture/vercel/3/output.mjs b/crates/swc_ecma_transforms_react/tests/jsx/fixture/3/output.mjs
similarity index 100%
rename from crates/swc_ecma_transforms_react/tests/jsx/fixture/vercel/3/output.mjs
rename to crates/swc_ecma_transforms_react/tests/jsx/fixture/3/output.mjs
diff --git a/crates/swc_ecma_transforms_react/tests/jsx/fixture/issue-2037/input.js b/crates/swc_ecma_transforms_react/tests/jsx/fixture/issue-2037/input.js
new file mode 100644
index 000000000000..9a314e322623
--- /dev/null
+++ b/crates/swc_ecma_transforms_react/tests/jsx/fixture/issue-2037/input.js
@@ -0,0 +1,3 @@
+const A = () => {
+ return {...[]}
;
+};
\ No newline at end of file
diff --git a/crates/swc_ecma_transforms_react/tests/jsx/fixture/issue-2037/output.mjs b/crates/swc_ecma_transforms_react/tests/jsx/fixture/issue-2037/output.mjs
new file mode 100644
index 000000000000..9ebb0e7369d8
--- /dev/null
+++ b/crates/swc_ecma_transforms_react/tests/jsx/fixture/issue-2037/output.mjs
@@ -0,0 +1,3 @@
+const A = ()=>{
+ return /*#__PURE__*/ React.createElement("div", null, ...[]);
+};
diff --git a/crates/swc_ecma_transforms_react/tests/jsx/fixture/react-automatic/should-disallow-spread-children/output.mjs b/crates/swc_ecma_transforms_react/tests/jsx/fixture/react-automatic/should-disallow-spread-children/output.mjs
index 33ec0c22bfb9..b8d3602b8bbd 100644
--- a/crates/swc_ecma_transforms_react/tests/jsx/fixture/react-automatic/should-disallow-spread-children/output.mjs
+++ b/crates/swc_ecma_transforms_react/tests/jsx/fixture/react-automatic/should-disallow-spread-children/output.mjs
@@ -1 +1 @@
-/*#__PURE__*/ React.createElement("div", null);
+/*#__PURE__*/ React.createElement("div", null, ...children);
diff --git a/crates/swc_ecma_transforms_react/tests/jsx/fixture/react-automatic/should-disallow-spread-children/output.stderr b/crates/swc_ecma_transforms_react/tests/jsx/fixture/react-automatic/should-disallow-spread-children/output.stderr
deleted file mode 100644
index e5ad4ab15390..000000000000
--- a/crates/swc_ecma_transforms_react/tests/jsx/fixture/react-automatic/should-disallow-spread-children/output.stderr
+++ /dev/null
@@ -1,6 +0,0 @@
-
- x Spread children are not supported in React.
- ,-[input.js:1:1]
- 1 | {...children}
;
- : ^^^^^^^^^^^^^
- `----
diff --git a/crates/swc_ecma_transforms_react/tests/jsx/fixture/react/should-disallow-spread-children/output.mjs b/crates/swc_ecma_transforms_react/tests/jsx/fixture/react/should-disallow-spread-children/output.mjs
index 33ec0c22bfb9..b8d3602b8bbd 100644
--- a/crates/swc_ecma_transforms_react/tests/jsx/fixture/react/should-disallow-spread-children/output.mjs
+++ b/crates/swc_ecma_transforms_react/tests/jsx/fixture/react/should-disallow-spread-children/output.mjs
@@ -1 +1 @@
-/*#__PURE__*/ React.createElement("div", null);
+/*#__PURE__*/ React.createElement("div", null, ...children);
diff --git a/crates/swc_ecma_transforms_react/tests/jsx/fixture/react/should-disallow-spread-children/output.stderr b/crates/swc_ecma_transforms_react/tests/jsx/fixture/react/should-disallow-spread-children/output.stderr
deleted file mode 100644
index e5ad4ab15390..000000000000
--- a/crates/swc_ecma_transforms_react/tests/jsx/fixture/react/should-disallow-spread-children/output.stderr
+++ /dev/null
@@ -1,6 +0,0 @@
-
- x Spread children are not supported in React.
- ,-[input.js:1:1]
- 1 | {...children}
;
- : ^^^^^^^^^^^^^
- `----