diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts
index 018e2ad2cb411..e274f3275f144 100644
--- a/src/compiler/transformers/jsx.ts
+++ b/src/compiler/transformers/jsx.ts
@@ -547,7 +547,8 @@ namespace ts {
}
function visitJsxExpression(node: JsxExpression) {
- return visitNode(node.expression, visitor, isExpression);
+ const expression = visitNode(node.expression, visitor, isExpression);
+ return node.dotDotDotToken ? factory.createSpreadElement(expression!) : expression;
}
}
diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js
index 177f997297b44..fbf032054279d 100644
--- a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js
+++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js
@@ -89,31 +89,36 @@ const _brokenTree2 = {tree}{tree}
//// [component.js]
"use strict";
+var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+ if (ar || !(i in from)) {
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+ ar[i] = from[i];
+ }
+ }
+ return to.concat(ar || Array.prototype.slice.call(from));
+};
var _this = this;
exports.__esModule = true;
exports.tree = exports.MyClass = exports.MySFC = void 0;
/** @jsx predom */
var renderer2_1 = require("./renderer2");
-var MySFC = function (props) { return (0, renderer2_1.predom)("p", null,
- props.x,
+var MySFC = function (props) { return renderer2_1.predom.apply(void 0, __spreadArray(["p", null, props.x,
" + ",
props.y,
" = ",
- props.x + props.y,
- _this.props.children); };
+ props.x + props.y], _this.props.children, false)); };
exports.MySFC = MySFC;
var MyClass = /** @class */ (function () {
function MyClass(props) {
this.props = props;
}
MyClass.prototype.render = function () {
- return (0, renderer2_1.predom)("p", null,
- this.props.x,
+ return renderer2_1.predom.apply(void 0, __spreadArray(["p", null, this.props.x,
" + ",
this.props.y,
" = ",
- this.props.x + this.props.y,
- this.props.children);
+ this.props.x + this.props.y], this.props.children, false));
};
return MyClass;
}());
@@ -124,6 +129,15 @@ exports.tree = (0, renderer2_1.predom)(exports.MySFC, { x: 1, y: 2 },
exports["default"] = (0, renderer2_1.predom)("h", null);
//// [index.js]
"use strict";
+var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+ if (ar || !(i in from)) {
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+ ar[i] = from[i];
+ }
+ }
+ return to.concat(ar || Array.prototype.slice.call(from));
+};
exports.__esModule = true;
/** @jsx dom */
var renderer_1 = require("./renderer");
@@ -142,13 +156,11 @@ var DOMClass = /** @class */ (function () {
this.props = props;
}
DOMClass.prototype.render = function () {
- return (0, renderer_1.dom)("p", null,
- this.props.x,
+ return renderer_1.dom.apply(void 0, __spreadArray(["p", null, this.props.x,
" + ",
this.props.y,
" = ",
- this.props.x + this.props.y,
- this.props.children);
+ this.props.x + this.props.y], this.props.children, false));
};
return DOMClass;
}());
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType.errors.txt b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).errors.txt
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType.errors.txt
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).errors.txt
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).js b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).js
new file mode 100644
index 0000000000000..a4d7219b0a617
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).js
@@ -0,0 +1,47 @@
+//// [tsxSpreadChildrenInvalidType.tsx]
+declare module JSX {
+ interface Element { }
+ interface IntrinsicElements {
+ [s: string]: any;
+ }
+}
+declare var React: any;
+
+interface TodoProp {
+ id: number;
+ todo: string;
+}
+interface TodoListProps {
+ todos: TodoProp[];
+}
+function Todo(prop: { key: number, todo: string }) {
+ return
{prop.key.toString() + prop.todo}
;
+}
+function TodoList({ todos }: TodoListProps) {
+ return
+ {...}
+
;
+}
+function TodoListNoError({ todos }: TodoListProps) {
+ // any is not checked
+ return
+ {...( as any)}
+
;
+}
+let x: TodoListProps;
+
+
+
+//// [tsxSpreadChildrenInvalidType.js]
+function Todo(prop) {
+ return React.createElement("div", null, prop.key.toString() + prop.todo);
+}
+function TodoList({ todos }) {
+ return React.createElement("div", null, ...React.createElement(Todo, { key: todos[0].id, todo: todos[0].todo }));
+}
+function TodoListNoError({ todos }) {
+ // any is not checked
+ return React.createElement("div", null, ...React.createElement(Todo, { key: todos[0].id, todo: todos[0].todo }));
+}
+let x;
+React.createElement(TodoList, Object.assign({}, x));
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType.symbols b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).symbols
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType.symbols
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).symbols
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType.types b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).types
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType.types
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).types
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).errors.txt b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).errors.txt
new file mode 100644
index 0000000000000..d1524c6bf3a97
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).errors.txt
@@ -0,0 +1,38 @@
+tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx(21,9): error TS2609: JSX spread child must be an array type.
+
+
+==== tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx (1 errors) ====
+ declare module JSX {
+ interface Element { }
+ interface IntrinsicElements {
+ [s: string]: any;
+ }
+ }
+ declare var React: any;
+
+ interface TodoProp {
+ id: number;
+ todo: string;
+ }
+ interface TodoListProps {
+ todos: TodoProp[];
+ }
+ function Todo(prop: { key: number, todo: string }) {
+ return {prop.key.toString() + prop.todo}
;
+ }
+ function TodoList({ todos }: TodoListProps) {
+ return
+ {...}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2609: JSX spread child must be an array type.
+
;
+ }
+ function TodoListNoError({ todos }: TodoListProps) {
+ // any is not checked
+ return
+ {...( as any)}
+
;
+ }
+ let x: TodoListProps;
+
+
\ No newline at end of file
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType.js b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).js
similarity index 66%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType.js
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).js
index d8c0025696994..bdf486f44d189 100644
--- a/tests/baselines/reference/tsxSpreadChildrenInvalidType.js
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).js
@@ -44,17 +44,26 @@ var __assign = (this && this.__assign) || function () {
};
return __assign.apply(this, arguments);
};
+var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
+ if (ar || !(i in from)) {
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
+ ar[i] = from[i];
+ }
+ }
+ return to.concat(ar || Array.prototype.slice.call(from));
+};
function Todo(prop) {
return React.createElement("div", null, prop.key.toString() + prop.todo);
}
function TodoList(_a) {
var todos = _a.todos;
- return React.createElement("div", null, React.createElement(Todo, { key: todos[0].id, todo: todos[0].todo }));
+ return React.createElement.apply(React, __spreadArray(["div", null], React.createElement(Todo, { key: todos[0].id, todo: todos[0].todo }), false));
}
function TodoListNoError(_a) {
var todos = _a.todos;
// any is not checked
- return React.createElement("div", null, React.createElement(Todo, { key: todos[0].id, todo: todos[0].todo }));
+ return React.createElement.apply(React, __spreadArray(["div", null], React.createElement(Todo, { key: todos[0].id, todo: todos[0].todo }), false));
}
var x;
React.createElement(TodoList, __assign({}, x));
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).symbols b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).symbols
new file mode 100644
index 0000000000000..5e41936f306e1
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).symbols
@@ -0,0 +1,104 @@
+=== tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx ===
+declare module JSX {
+>JSX : Symbol(JSX, Decl(tsxSpreadChildrenInvalidType.tsx, 0, 0))
+
+ interface Element { }
+>Element : Symbol(Element, Decl(tsxSpreadChildrenInvalidType.tsx, 0, 20))
+
+ interface IntrinsicElements {
+>IntrinsicElements : Symbol(IntrinsicElements, Decl(tsxSpreadChildrenInvalidType.tsx, 1, 22))
+
+ [s: string]: any;
+>s : Symbol(s, Decl(tsxSpreadChildrenInvalidType.tsx, 3, 3))
+ }
+}
+declare var React: any;
+>React : Symbol(React, Decl(tsxSpreadChildrenInvalidType.tsx, 6, 11))
+
+interface TodoProp {
+>TodoProp : Symbol(TodoProp, Decl(tsxSpreadChildrenInvalidType.tsx, 6, 23))
+
+ id: number;
+>id : Symbol(TodoProp.id, Decl(tsxSpreadChildrenInvalidType.tsx, 8, 20))
+
+ todo: string;
+>todo : Symbol(TodoProp.todo, Decl(tsxSpreadChildrenInvalidType.tsx, 9, 15))
+}
+interface TodoListProps {
+>TodoListProps : Symbol(TodoListProps, Decl(tsxSpreadChildrenInvalidType.tsx, 11, 1))
+
+ todos: TodoProp[];
+>todos : Symbol(TodoListProps.todos, Decl(tsxSpreadChildrenInvalidType.tsx, 12, 25))
+>TodoProp : Symbol(TodoProp, Decl(tsxSpreadChildrenInvalidType.tsx, 6, 23))
+}
+function Todo(prop: { key: number, todo: string }) {
+>Todo : Symbol(Todo, Decl(tsxSpreadChildrenInvalidType.tsx, 14, 1))
+>prop : Symbol(prop, Decl(tsxSpreadChildrenInvalidType.tsx, 15, 14))
+>key : Symbol(key, Decl(tsxSpreadChildrenInvalidType.tsx, 15, 21))
+>todo : Symbol(todo, Decl(tsxSpreadChildrenInvalidType.tsx, 15, 34))
+
+ return {prop.key.toString() + prop.todo}
;
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxSpreadChildrenInvalidType.tsx, 1, 22))
+>prop.key.toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
+>prop.key : Symbol(key, Decl(tsxSpreadChildrenInvalidType.tsx, 15, 21))
+>prop : Symbol(prop, Decl(tsxSpreadChildrenInvalidType.tsx, 15, 14))
+>key : Symbol(key, Decl(tsxSpreadChildrenInvalidType.tsx, 15, 21))
+>toString : Symbol(Number.toString, Decl(lib.es5.d.ts, --, --))
+>prop.todo : Symbol(todo, Decl(tsxSpreadChildrenInvalidType.tsx, 15, 34))
+>prop : Symbol(prop, Decl(tsxSpreadChildrenInvalidType.tsx, 15, 14))
+>todo : Symbol(todo, Decl(tsxSpreadChildrenInvalidType.tsx, 15, 34))
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxSpreadChildrenInvalidType.tsx, 1, 22))
+}
+function TodoList({ todos }: TodoListProps) {
+>TodoList : Symbol(TodoList, Decl(tsxSpreadChildrenInvalidType.tsx, 17, 1))
+>todos : Symbol(todos, Decl(tsxSpreadChildrenInvalidType.tsx, 18, 19))
+>TodoListProps : Symbol(TodoListProps, Decl(tsxSpreadChildrenInvalidType.tsx, 11, 1))
+
+ return
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxSpreadChildrenInvalidType.tsx, 1, 22))
+
+ {...}
+>Todo : Symbol(Todo, Decl(tsxSpreadChildrenInvalidType.tsx, 14, 1))
+>key : Symbol(key, Decl(tsxSpreadChildrenInvalidType.tsx, 20, 17))
+>todos[0].id : Symbol(TodoProp.id, Decl(tsxSpreadChildrenInvalidType.tsx, 8, 20))
+>todos : Symbol(todos, Decl(tsxSpreadChildrenInvalidType.tsx, 18, 19))
+>id : Symbol(TodoProp.id, Decl(tsxSpreadChildrenInvalidType.tsx, 8, 20))
+>todo : Symbol(todo, Decl(tsxSpreadChildrenInvalidType.tsx, 20, 35))
+>todos[0].todo : Symbol(TodoProp.todo, Decl(tsxSpreadChildrenInvalidType.tsx, 9, 15))
+>todos : Symbol(todos, Decl(tsxSpreadChildrenInvalidType.tsx, 18, 19))
+>todo : Symbol(TodoProp.todo, Decl(tsxSpreadChildrenInvalidType.tsx, 9, 15))
+
+
;
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxSpreadChildrenInvalidType.tsx, 1, 22))
+}
+function TodoListNoError({ todos }: TodoListProps) {
+>TodoListNoError : Symbol(TodoListNoError, Decl(tsxSpreadChildrenInvalidType.tsx, 22, 1))
+>todos : Symbol(todos, Decl(tsxSpreadChildrenInvalidType.tsx, 23, 26))
+>TodoListProps : Symbol(TodoListProps, Decl(tsxSpreadChildrenInvalidType.tsx, 11, 1))
+
+ // any is not checked
+ return
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxSpreadChildrenInvalidType.tsx, 1, 22))
+
+ {...( as any)}
+>Todo : Symbol(Todo, Decl(tsxSpreadChildrenInvalidType.tsx, 14, 1))
+>key : Symbol(key, Decl(tsxSpreadChildrenInvalidType.tsx, 26, 18))
+>todos[0].id : Symbol(TodoProp.id, Decl(tsxSpreadChildrenInvalidType.tsx, 8, 20))
+>todos : Symbol(todos, Decl(tsxSpreadChildrenInvalidType.tsx, 23, 26))
+>id : Symbol(TodoProp.id, Decl(tsxSpreadChildrenInvalidType.tsx, 8, 20))
+>todo : Symbol(todo, Decl(tsxSpreadChildrenInvalidType.tsx, 26, 36))
+>todos[0].todo : Symbol(TodoProp.todo, Decl(tsxSpreadChildrenInvalidType.tsx, 9, 15))
+>todos : Symbol(todos, Decl(tsxSpreadChildrenInvalidType.tsx, 23, 26))
+>todo : Symbol(TodoProp.todo, Decl(tsxSpreadChildrenInvalidType.tsx, 9, 15))
+
+
;
+>div : Symbol(JSX.IntrinsicElements, Decl(tsxSpreadChildrenInvalidType.tsx, 1, 22))
+}
+let x: TodoListProps;
+>x : Symbol(x, Decl(tsxSpreadChildrenInvalidType.tsx, 29, 3))
+>TodoListProps : Symbol(TodoListProps, Decl(tsxSpreadChildrenInvalidType.tsx, 11, 1))
+
+
+>TodoList : Symbol(TodoList, Decl(tsxSpreadChildrenInvalidType.tsx, 17, 1))
+>x : Symbol(x, Decl(tsxSpreadChildrenInvalidType.tsx, 29, 3))
+
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).types b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).types
new file mode 100644
index 0000000000000..b8eb048703703
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).types
@@ -0,0 +1,108 @@
+=== tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx ===
+declare module JSX {
+ interface Element { }
+ interface IntrinsicElements {
+ [s: string]: any;
+>s : string
+ }
+}
+declare var React: any;
+>React : any
+
+interface TodoProp {
+ id: number;
+>id : number
+
+ todo: string;
+>todo : string
+}
+interface TodoListProps {
+ todos: TodoProp[];
+>todos : TodoProp[]
+}
+function Todo(prop: { key: number, todo: string }) {
+>Todo : (prop: { key: number; todo: string;}) => JSX.Element
+>prop : { key: number; todo: string; }
+>key : number
+>todo : string
+
+ return {prop.key.toString() + prop.todo}
;
+>{prop.key.toString() + prop.todo}
: JSX.Element
+>div : any
+>prop.key.toString() + prop.todo : string
+>prop.key.toString() : string
+>prop.key.toString : (radix?: number) => string
+>prop.key : number
+>prop : { key: number; todo: string; }
+>key : number
+>toString : (radix?: number) => string
+>prop.todo : string
+>prop : { key: number; todo: string; }
+>todo : string
+>div : any
+}
+function TodoList({ todos }: TodoListProps) {
+>TodoList : ({ todos }: TodoListProps) => JSX.Element
+>todos : TodoProp[]
+
+ return
+>
{...}
: JSX.Element
+>div : any
+
+ {...
}
+>
: JSX.Element
+>Todo : (prop: { key: number; todo: string; }) => JSX.Element
+>key : number
+>todos[0].id : number
+>todos[0] : TodoProp
+>todos : TodoProp[]
+>0 : 0
+>id : number
+>todo : string
+>todos[0].todo : string
+>todos[0] : TodoProp
+>todos : TodoProp[]
+>0 : 0
+>todo : string
+
+
;
+>div : any
+}
+function TodoListNoError({ todos }: TodoListProps) {
+>TodoListNoError : ({ todos }: TodoListProps) => JSX.Element
+>todos : TodoProp[]
+
+ // any is not checked
+ return
+>
{...( as any)}
: JSX.Element
+>div : any
+
+ {...(
as any)}
+>(
as any) : any
+>
as any : any
+>
: JSX.Element
+>Todo : (prop: { key: number; todo: string; }) => JSX.Element
+>key : number
+>todos[0].id : number
+>todos[0] : TodoProp
+>todos : TodoProp[]
+>0 : 0
+>id : number
+>todo : string
+>todos[0].todo : string
+>todos[0] : TodoProp
+>todos : TodoProp[]
+>0 : 0
+>todo : string
+
+
;
+>div : any
+}
+let x: TodoListProps;
+>x : TodoListProps
+
+
+> : JSX.Element
+>TodoList : ({ todos }: TodoListProps) => JSX.Element
+>x : TodoListProps
+
diff --git a/tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx b/tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx
index 41181618ce0a3..49067bbc4b02e 100644
--- a/tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx
+++ b/tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx
@@ -1,4 +1,5 @@
// @jsx: react
+// @target: es2015,es5
declare module JSX {
interface Element { }
interface IntrinsicElements {