diff --git a/src/compiler/transformers/jsx.ts b/src/compiler/transformers/jsx.ts
index 166a91dfa69b8..2394e25a354df 100644
--- a/src/compiler/transformers/jsx.ts
+++ b/src/compiler/transformers/jsx.ts
@@ -26,12 +26,12 @@ namespace ts {
return currentFileState.filenameDeclaration.name;
}
- function getJsxFactoryCalleePrimitive(childrenLength: number): "jsx" | "jsxs" | "jsxDEV" {
- return compilerOptions.jsx === JsxEmit.ReactJSXDev ? "jsxDEV" : childrenLength > 1 ? "jsxs" : "jsx";
+ function getJsxFactoryCalleePrimitive(isStaticChildren: boolean): "jsx" | "jsxs" | "jsxDEV" {
+ return compilerOptions.jsx === JsxEmit.ReactJSXDev ? "jsxDEV" : isStaticChildren ? "jsxs" : "jsx";
}
- function getJsxFactoryCallee(childrenLength: number) {
- const type = getJsxFactoryCalleePrimitive(childrenLength);
+ function getJsxFactoryCallee(isStaticChildren: boolean) {
+ const type = getJsxFactoryCalleePrimitive(isStaticChildren);
return getImplicitImportForName(type);
}
@@ -206,7 +206,7 @@ namespace ts {
function convertJsxChildrenToChildrenPropAssignment(children: readonly JsxChild[]) {
const nonWhitespaceChildren = getSemanticJsxChildren(children);
- if (length(nonWhitespaceChildren) === 1) {
+ if (length(nonWhitespaceChildren) === 1 && !(nonWhitespaceChildren[0] as JsxExpression).dotDotDotToken) {
const result = transformJsxChildToExpression(nonWhitespaceChildren[0]);
return result && factory.createPropertyAssignment("children", result);
}
@@ -221,16 +221,33 @@ namespace ts {
const attrs = keyAttr ? filter(node.attributes.properties, p => p !== keyAttr) : node.attributes.properties;
const objectProperties = length(attrs) ? transformJsxAttributesToObjectProps(attrs, childrenProp) :
factory.createObjectLiteralExpression(childrenProp ? [childrenProp] : emptyArray); // When there are no attributes, React wants {}
- return visitJsxOpeningLikeElementOrFragmentJSX(tagName, objectProperties, keyAttr, length(getSemanticJsxChildren(children || emptyArray)), isChild, location);
+ return visitJsxOpeningLikeElementOrFragmentJSX(
+ tagName,
+ objectProperties,
+ keyAttr,
+ children || emptyArray,
+ isChild,
+ location
+ );
}
- function visitJsxOpeningLikeElementOrFragmentJSX(tagName: Expression, objectProperties: Expression, keyAttr: JsxAttribute | undefined, childrenLength: number, isChild: boolean, location: TextRange) {
+ function visitJsxOpeningLikeElementOrFragmentJSX(
+ tagName: Expression,
+ objectProperties: Expression,
+ keyAttr: JsxAttribute | undefined,
+ children: readonly JsxChild[],
+ isChild: boolean,
+ location: TextRange
+ ) {
+ const nonWhitespaceChildren = getSemanticJsxChildren(children);
+ const isStaticChildren =
+ length(nonWhitespaceChildren) > 1 || !!(nonWhitespaceChildren[0] as JsxExpression)?.dotDotDotToken;
const args: Expression[] = [tagName, objectProperties, !keyAttr ? factory.createVoidZero() : transformJsxAttributeInitializer(keyAttr.initializer)];
if (compilerOptions.jsx === JsxEmit.ReactJSXDev) {
const originalFile = getOriginalNode(currentSourceFile);
if (originalFile && isSourceFile(originalFile)) {
// isStaticChildren development flag
- args.push(childrenLength > 1 ? factory.createTrue() : factory.createFalse());
+ args.push(isStaticChildren ? factory.createTrue() : factory.createFalse());
// __source development flag
const lineCol = getLineAndCharacterOfPosition(originalFile, location.pos);
args.push(factory.createObjectLiteralExpression([
@@ -242,7 +259,10 @@ namespace ts {
args.push(factory.createThis());
}
}
- const element = setTextRange(factory.createCallExpression(getJsxFactoryCallee(childrenLength), /*typeArguments*/ undefined, args), location);
+ const element = setTextRange(
+ factory.createCallExpression(getJsxFactoryCallee(isStaticChildren), /*typeArguments*/ undefined, args),
+ location
+ );
if (isChild) {
startOnNewLine(element);
@@ -294,7 +314,7 @@ namespace ts {
getImplicitJsxFragmentReference(),
childrenProps || factory.createObjectLiteralExpression([]),
/*keyAttr*/ undefined,
- length(getSemanticJsxChildren(children)),
+ children,
isChild,
location
);
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).errors.txt b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es2015).errors.txt
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).errors.txt
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es2015).errors.txt
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).js b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es2015).js
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).js
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es2015).js
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).symbols b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es2015).symbols
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).symbols
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es2015).symbols
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).types b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es2015).types
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es2015).types
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es2015).types
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).errors.txt b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es5).errors.txt
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).errors.txt
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es5).errors.txt
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).js b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es5).js
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).js
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es5).js
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).symbols b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es5).symbols
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).symbols
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es5).symbols
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).types b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es5).types
similarity index 100%
rename from tests/baselines/reference/tsxSpreadChildrenInvalidType(target=es5).types
rename to tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react,target=es5).types
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es2015).errors.txt b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es2015).errors.txt
new file mode 100644
index 0000000000000..829e229a91c63
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es2015).errors.txt
@@ -0,0 +1,41 @@
+tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx(17,12): error TS2792: Cannot find module 'react/jsx-runtime'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
+tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx(21,9): error TS2609: JSX spread child must be an array type.
+
+
+==== tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx (2 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}
;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2792: Cannot find module 'react/jsx-runtime'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
+ }
+ 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(jsx=react-jsx,target=es2015).js b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es2015).js
new file mode 100644
index 0000000000000..75ff44138c806
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,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 _jsx("div", { children: prop.key.toString() + prop.todo }, void 0);
+}
+function TodoList({ todos }) {
+ return _jsxs("div", { children: [..._jsx(Todo, { todo: todos[0].todo }, todos[0].id)] }, void 0);
+}
+function TodoListNoError({ todos }) {
+ // any is not checked
+ return _jsxs("div", { children: [..._jsx(Todo, { todo: todos[0].todo }, todos[0].id)] }, void 0);
+}
+let x;
+_jsx(TodoList, Object.assign({}, x), void 0);
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es2015).symbols b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es2015).symbols
new file mode 100644
index 0000000000000..5e41936f306e1
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es2015).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(jsx=react-jsx,target=es2015).types b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es2015).types
new file mode 100644
index 0000000000000..b8eb048703703
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es2015).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/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es5).errors.txt b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es5).errors.txt
new file mode 100644
index 0000000000000..acefceb65ba5c
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es5).errors.txt
@@ -0,0 +1,41 @@
+tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx(17,12): error TS2307: Cannot find module 'react/jsx-runtime' or its corresponding type declarations.
+tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx(21,9): error TS2609: JSX spread child must be an array type.
+
+
+==== tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx (2 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}
;
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2307: Cannot find module 'react/jsx-runtime' or its corresponding type declarations.
+ }
+ 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(jsx=react-jsx,target=es5).js b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es5).js
new file mode 100644
index 0000000000000..00f8cda36dd54
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es5).js
@@ -0,0 +1,69 @@
+//// [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]
+var __assign = (this && this.__assign) || function () {
+ __assign = Object.assign || function(t) {
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
+ s = arguments[i];
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+ t[p] = s[p];
+ }
+ return t;
+ };
+ 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 (0, _a.jsx)("div", { children: prop.key.toString() + prop.todo }, void 0);
+}
+function TodoList(_a) {
+ var todos = _a.todos;
+ return (0, _b.jsxs)("div", { children: __spreadArray([], (0, _a.jsx)(Todo, { todo: todos[0].todo }, todos[0].id), true) }, void 0);
+}
+function TodoListNoError(_a) {
+ var todos = _a.todos;
+ // any is not checked
+ return (0, _b.jsxs)("div", { children: __spreadArray([], (0, _a.jsx)(Todo, { todo: todos[0].todo }, todos[0].id), true) }, void 0);
+}
+var x;
+(0, _a.jsx)(TodoList, __assign({}, x), void 0);
diff --git a/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es5).symbols b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es5).symbols
new file mode 100644
index 0000000000000..5e41936f306e1
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,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(jsx=react-jsx,target=es5).types b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,target=es5).types
new file mode 100644
index 0000000000000..b8eb048703703
--- /dev/null
+++ b/tests/baselines/reference/tsxSpreadChildrenInvalidType(jsx=react-jsx,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 49067bbc4b02e..77a9b054b2c34 100644
--- a/tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx
+++ b/tests/cases/conformance/jsx/tsxSpreadChildrenInvalidType.tsx
@@ -1,4 +1,4 @@
-// @jsx: react
+// @jsx: react,react-jsx
// @target: es2015,es5
declare module JSX {
interface Element { }