Fix children prop for react-jsx and react-jsxdev (#40630)

* Fix children prop for `react-jsx` and `react-jsxdev`

* Add tests
This commit is contained in:
Hikari Hayashi 2020-09-19 05:26:20 +08:00 committed by GitHub
parent 6c6ddfe5c0
commit f1ac8cd93f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 88 additions and 13 deletions

View File

@ -208,33 +208,36 @@ namespace ts {
let objectProperties: Expression;
const keyAttr = find(node.attributes.properties, p => !!p.name && isIdentifier(p.name) && p.name.escapedText === "key") as JsxAttribute | undefined;
const attrs = keyAttr ? filter(node.attributes.properties, p => p !== keyAttr) : node.attributes.properties;
if (attrs.length === 0) {
objectProperties = factory.createObjectLiteralExpression([]);
// When there are no attributes, React wants {}
}
else {
let segments: Expression[] = [];
if (attrs.length) {
// Map spans of JsxAttribute nodes into object literals and spans
// of JsxSpreadAttribute nodes into expressions.
const segments = flatten<Expression | ObjectLiteralExpression>(
segments = flatten(
spanMap(attrs, isJsxSpreadAttribute, (attrs, isSpread) => isSpread
? map(attrs, transformJsxSpreadAttributeToExpression)
: factory.createObjectLiteralExpression(map(attrs, transformJsxAttributeToObjectLiteralElement))
)
);
if (children && children.length) {
const result = convertJsxChildrenToChildrenPropObject(children);
if (result) {
segments.push(result);
}
}
if (isJsxSpreadAttribute(attrs[0])) {
// We must always emit at least one object literal before a spread
// argument.factory.createObjectLiteral
segments.unshift(factory.createObjectLiteralExpression());
}
}
if (children && children.length) {
const result = convertJsxChildrenToChildrenPropObject(children);
if (result) {
segments.push(result);
}
}
if (segments.length === 0) {
objectProperties = factory.createObjectLiteralExpression([]);
// When there are no attributes, React wants {}
}
else {
// Either emit one big object literal (no spread attribs), or
// a call to the __assign helper.
objectProperties = singleOrUndefined(segments) || emitHelpers().createAssignHelper(segments);

View File

@ -0,0 +1,13 @@
//// [jsxJsxsCjsTransformChildren.tsx]
/// <reference path="/.lib/react16.d.ts" />
const a = <div>text</div>;
export {};
//// [jsxJsxsCjsTransformChildren.js]
"use strict";
exports.__esModule = true;
var jsx_runtime_1 = require("react/jsx-runtime");
/// <reference path="react16.d.ts" />
var a = jsx_runtime_1.jsx("div", { children: "text" }, void 0);

View File

@ -0,0 +1,9 @@
=== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformChildren.tsx ===
/// <reference path="react16.d.ts" />
const a = <div>text</div>;
>a : Symbol(a, Decl(jsxJsxsCjsTransformChildren.tsx, 1, 5))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
export {};

View File

@ -0,0 +1,10 @@
=== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformChildren.tsx ===
/// <reference path="react16.d.ts" />
const a = <div>text</div>;
>a : JSX.Element
><div>text</div> : JSX.Element
>div : any
>div : any
export {};

View File

@ -0,0 +1,14 @@
//// [jsxJsxsCjsTransformChildren.tsx]
/// <reference path="/.lib/react16.d.ts" />
const a = <div>text</div>;
export {};
//// [jsxJsxsCjsTransformChildren.js]
"use strict";
exports.__esModule = true;
var jsx_dev_runtime_1 = require("react/jsx-dev-runtime");
var _jsxFileName = "tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformChildren.tsx";
/// <reference path="react16.d.ts" />
var a = jsx_dev_runtime_1.jsxDEV("div", { children: "text" }, void 0, false, { fileName: _jsxFileName, lineNumber: 2, columnNumber: 10 }, this);

View File

@ -0,0 +1,9 @@
=== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformChildren.tsx ===
/// <reference path="react16.d.ts" />
const a = <div>text</div>;
>a : Symbol(a, Decl(jsxJsxsCjsTransformChildren.tsx, 1, 5))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
>div : Symbol(JSX.IntrinsicElements.div, Decl(react16.d.ts, 2420, 114))
export {};

View File

@ -0,0 +1,10 @@
=== tests/cases/conformance/jsx/jsxs/jsxJsxsCjsTransformChildren.tsx ===
/// <reference path="react16.d.ts" />
const a = <div>text</div>;
>a : JSX.Element
><div>text</div> : JSX.Element
>div : any
>div : any
export {};

View File

@ -0,0 +1,7 @@
// @jsx: react-jsx,react-jsxdev
// @strict: true
// @module: commonjs
/// <reference path="/.lib/react16.d.ts" />
const a = <div>text</div>;
export {};