Skip to content

Commit 0e371c4

Browse files
authored
fix: do not use JSX.ElementChildrenAttribute under jsx: react-jsx or jsx: react-jsxdev (#60880)
1 parent 2c865e4 commit 0e371c4

17 files changed

+772
-0
lines changed

src/compiler/checker.ts

+4
Original file line numberDiff line numberDiff line change
@@ -33472,6 +33472,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
3347233472
}
3347333473

3347433474
function getJsxElementChildrenPropertyName(jsxNamespace: Symbol): __String | undefined {
33475+
if (compilerOptions.jsx === JsxEmit.ReactJSX || compilerOptions.jsx === JsxEmit.ReactJSXDev) {
33476+
// In these JsxEmit modes the children property is fixed to 'children'
33477+
return "children" as __String;
33478+
}
3347533479
return getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer, jsxNamespace);
3347633480
}
3347733481

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/test.tsx(7,2): error TS2741: Property 'offspring' is missing in type '{ children: string; }' but required in type '{ offspring: string; }'.
2+
3+
4+
==== /jsx.d.ts (0 errors) ====
5+
declare namespace JSX {
6+
interface IntrinsicElements {
7+
h1: { children: string }
8+
}
9+
10+
type Element = string;
11+
12+
interface ElementChildrenAttribute {
13+
offspring: any;
14+
}
15+
}
16+
17+
==== /test.tsx (1 errors) ====
18+
const Title = (props: { children: string }) => <h1>{props.children}</h1>;
19+
20+
<Title>Hello, world!</Title>;
21+
22+
const Wrong = (props: { offspring: string }) => <h1>{props.offspring}</h1>;
23+
24+
<Wrong>Byebye, world!</Wrong>
25+
~~~~~
26+
!!! error TS2741: Property 'offspring' is missing in type '{ children: string; }' but required in type '{ offspring: string; }'.
27+
!!! related TS2728 /test.tsx:5:25: 'offspring' is declared here.
28+
29+
==== /jsx/jsx-runtime.ts (0 errors) ====
30+
export {};
31+
==== /jsx/jsx-dev-runtime.ts (0 errors) ====
32+
export {};
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//// [tests/cases/compiler/jsxNamespaceElementChildrenAttributeIgnoredWhenReactJsx.tsx] ////
2+
3+
//// [jsx.d.ts]
4+
declare namespace JSX {
5+
interface IntrinsicElements {
6+
h1: { children: string }
7+
}
8+
9+
type Element = string;
10+
11+
interface ElementChildrenAttribute {
12+
offspring: any;
13+
}
14+
}
15+
16+
//// [test.tsx]
17+
const Title = (props: { children: string }) => <h1>{props.children}</h1>;
18+
19+
<Title>Hello, world!</Title>;
20+
21+
const Wrong = (props: { offspring: string }) => <h1>{props.offspring}</h1>;
22+
23+
<Wrong>Byebye, world!</Wrong>
24+
25+
//// [jsx-runtime.ts]
26+
export {};
27+
//// [jsx-dev-runtime.ts]
28+
export {};
29+
30+
31+
//// [jsx-runtime.js]
32+
"use strict";
33+
Object.defineProperty(exports, "__esModule", { value: true });
34+
//// [test.js]
35+
"use strict";
36+
Object.defineProperty(exports, "__esModule", { value: true });
37+
var jsx_runtime_1 = require("/jsx/jsx-runtime");
38+
var Title = function (props) { return (0, jsx_runtime_1.jsx)("h1", { children: props.children }); };
39+
(0, jsx_runtime_1.jsx)(Title, { children: "Hello, world!" });
40+
var Wrong = function (props) { return (0, jsx_runtime_1.jsx)("h1", { children: props.offspring }); };
41+
(0, jsx_runtime_1.jsx)(Wrong, { children: "Byebye, world!" });
42+
//// [jsx-dev-runtime.js]
43+
"use strict";
44+
Object.defineProperty(exports, "__esModule", { value: true });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//// [tests/cases/compiler/jsxNamespaceElementChildrenAttributeIgnoredWhenReactJsx.tsx] ////
2+
3+
=== /jsx.d.ts ===
4+
declare namespace JSX {
5+
>JSX : Symbol(JSX, Decl(jsx.d.ts, 0, 0))
6+
7+
interface IntrinsicElements {
8+
>IntrinsicElements : Symbol(IntrinsicElements, Decl(jsx.d.ts, 0, 23))
9+
10+
h1: { children: string }
11+
>h1 : Symbol(IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
12+
>children : Symbol(children, Decl(jsx.d.ts, 2, 9))
13+
}
14+
15+
type Element = string;
16+
>Element : Symbol(Element, Decl(jsx.d.ts, 3, 3))
17+
18+
interface ElementChildrenAttribute {
19+
>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(jsx.d.ts, 5, 24))
20+
21+
offspring: any;
22+
>offspring : Symbol(ElementChildrenAttribute.offspring, Decl(jsx.d.ts, 7, 38))
23+
}
24+
}
25+
26+
=== /test.tsx ===
27+
const Title = (props: { children: string }) => <h1>{props.children}</h1>;
28+
>Title : Symbol(Title, Decl(test.tsx, 0, 5))
29+
>props : Symbol(props, Decl(test.tsx, 0, 15))
30+
>children : Symbol(children, Decl(test.tsx, 0, 23))
31+
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
32+
>props.children : Symbol(children, Decl(test.tsx, 0, 23))
33+
>props : Symbol(props, Decl(test.tsx, 0, 15))
34+
>children : Symbol(children, Decl(test.tsx, 0, 23))
35+
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
36+
37+
<Title>Hello, world!</Title>;
38+
>Title : Symbol(Title, Decl(test.tsx, 0, 5))
39+
>Title : Symbol(Title, Decl(test.tsx, 0, 5))
40+
41+
const Wrong = (props: { offspring: string }) => <h1>{props.offspring}</h1>;
42+
>Wrong : Symbol(Wrong, Decl(test.tsx, 4, 5))
43+
>props : Symbol(props, Decl(test.tsx, 4, 15))
44+
>offspring : Symbol(offspring, Decl(test.tsx, 4, 23))
45+
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
46+
>props.offspring : Symbol(offspring, Decl(test.tsx, 4, 23))
47+
>props : Symbol(props, Decl(test.tsx, 4, 15))
48+
>offspring : Symbol(offspring, Decl(test.tsx, 4, 23))
49+
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
50+
51+
<Wrong>Byebye, world!</Wrong>
52+
>Wrong : Symbol(Wrong, Decl(test.tsx, 4, 5))
53+
>Wrong : Symbol(Wrong, Decl(test.tsx, 4, 5))
54+
55+
=== /jsx/jsx-runtime.ts ===
56+
57+
export {};
58+
=== /jsx/jsx-dev-runtime.ts ===
59+
60+
export {};
61+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
//// [tests/cases/compiler/jsxNamespaceElementChildrenAttributeIgnoredWhenReactJsx.tsx] ////
2+
3+
=== /jsx.d.ts ===
4+
declare namespace JSX {
5+
interface IntrinsicElements {
6+
h1: { children: string }
7+
>h1 : { children: string; }
8+
> : ^^^^^^^^^^^^ ^^^
9+
>children : string
10+
> : ^^^^^^
11+
}
12+
13+
type Element = string;
14+
>Element : string
15+
> : ^^^^^^
16+
17+
interface ElementChildrenAttribute {
18+
offspring: any;
19+
>offspring : any
20+
> : ^^^
21+
}
22+
}
23+
24+
=== /test.tsx ===
25+
const Title = (props: { children: string }) => <h1>{props.children}</h1>;
26+
>Title : (props: { children: string; }) => string
27+
> : ^ ^^ ^^^^^^^^^^^
28+
>(props: { children: string }) => <h1>{props.children}</h1> : (props: { children: string; }) => string
29+
> : ^ ^^ ^^^^^^^^^^^
30+
>props : { children: string; }
31+
> : ^^^^^^^^^^^^ ^^^
32+
>children : string
33+
> : ^^^^^^
34+
><h1>{props.children}</h1> : string
35+
> : ^^^^^^
36+
>h1 : any
37+
> : ^^^
38+
>props.children : string
39+
> : ^^^^^^
40+
>props : { children: string; }
41+
> : ^^^^^^^^^^^^ ^^^
42+
>children : string
43+
> : ^^^^^^
44+
>h1 : any
45+
> : ^^^
46+
47+
<Title>Hello, world!</Title>;
48+
><Title>Hello, world!</Title> : string
49+
> : ^^^^^^
50+
>Title : (props: { children: string; }) => string
51+
> : ^ ^^ ^^^^^^^^^^^
52+
>Title : (props: { children: string; }) => string
53+
> : ^ ^^ ^^^^^^^^^^^
54+
55+
const Wrong = (props: { offspring: string }) => <h1>{props.offspring}</h1>;
56+
>Wrong : (props: { offspring: string; }) => string
57+
> : ^ ^^ ^^^^^^^^^^^
58+
>(props: { offspring: string }) => <h1>{props.offspring}</h1> : (props: { offspring: string; }) => string
59+
> : ^ ^^ ^^^^^^^^^^^
60+
>props : { offspring: string; }
61+
> : ^^^^^^^^^^^^^ ^^^
62+
>offspring : string
63+
> : ^^^^^^
64+
><h1>{props.offspring}</h1> : string
65+
> : ^^^^^^
66+
>h1 : any
67+
> : ^^^
68+
>props.offspring : string
69+
> : ^^^^^^
70+
>props : { offspring: string; }
71+
> : ^^^^^^^^^^^^^ ^^^
72+
>offspring : string
73+
> : ^^^^^^
74+
>h1 : any
75+
> : ^^^
76+
77+
<Wrong>Byebye, world!</Wrong>
78+
><Wrong>Byebye, world!</Wrong> : string
79+
> : ^^^^^^
80+
>Wrong : (props: { offspring: string; }) => string
81+
> : ^ ^^ ^^^^^^^^^^^
82+
>Wrong : (props: { offspring: string; }) => string
83+
> : ^ ^^ ^^^^^^^^^^^
84+
85+
=== /jsx/jsx-runtime.ts ===
86+
87+
export {};
88+
=== /jsx/jsx-dev-runtime.ts ===
89+
90+
export {};
91+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/test.tsx(7,2): error TS2741: Property 'offspring' is missing in type '{ children: string; }' but required in type '{ offspring: string; }'.
2+
3+
4+
==== /jsx.d.ts (0 errors) ====
5+
declare namespace JSX {
6+
interface IntrinsicElements {
7+
h1: { children: string }
8+
}
9+
10+
type Element = string;
11+
12+
interface ElementChildrenAttribute {
13+
offspring: any;
14+
}
15+
}
16+
17+
==== /test.tsx (1 errors) ====
18+
const Title = (props: { children: string }) => <h1>{props.children}</h1>;
19+
20+
<Title>Hello, world!</Title>;
21+
22+
const Wrong = (props: { offspring: string }) => <h1>{props.offspring}</h1>;
23+
24+
<Wrong>Byebye, world!</Wrong>
25+
~~~~~
26+
!!! error TS2741: Property 'offspring' is missing in type '{ children: string; }' but required in type '{ offspring: string; }'.
27+
!!! related TS2728 /test.tsx:5:25: 'offspring' is declared here.
28+
29+
==== /jsx/jsx-runtime.ts (0 errors) ====
30+
export {};
31+
==== /jsx/jsx-dev-runtime.ts (0 errors) ====
32+
export {};
33+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
//// [tests/cases/compiler/jsxNamespaceElementChildrenAttributeIgnoredWhenReactJsx.tsx] ////
2+
3+
//// [jsx.d.ts]
4+
declare namespace JSX {
5+
interface IntrinsicElements {
6+
h1: { children: string }
7+
}
8+
9+
type Element = string;
10+
11+
interface ElementChildrenAttribute {
12+
offspring: any;
13+
}
14+
}
15+
16+
//// [test.tsx]
17+
const Title = (props: { children: string }) => <h1>{props.children}</h1>;
18+
19+
<Title>Hello, world!</Title>;
20+
21+
const Wrong = (props: { offspring: string }) => <h1>{props.offspring}</h1>;
22+
23+
<Wrong>Byebye, world!</Wrong>
24+
25+
//// [jsx-runtime.ts]
26+
export {};
27+
//// [jsx-dev-runtime.ts]
28+
export {};
29+
30+
31+
//// [jsx-dev-runtime.js]
32+
"use strict";
33+
Object.defineProperty(exports, "__esModule", { value: true });
34+
//// [test.js]
35+
"use strict";
36+
var _this = this;
37+
Object.defineProperty(exports, "__esModule", { value: true });
38+
var jsx_dev_runtime_1 = require("/jsx/jsx-dev-runtime");
39+
var _jsxFileName = "/test.tsx";
40+
var Title = function (props) { return (0, jsx_dev_runtime_1.jsxDEV)("h1", { children: props.children }, void 0, false, { fileName: _jsxFileName, lineNumber: 1, columnNumber: 47 }, _this); };
41+
(0, jsx_dev_runtime_1.jsxDEV)(Title, { children: "Hello, world!" }, void 0, false, { fileName: _jsxFileName, lineNumber: 1, columnNumber: 74 }, this);
42+
var Wrong = function (props) { return (0, jsx_dev_runtime_1.jsxDEV)("h1", { children: props.offspring }, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 48 }, _this); };
43+
(0, jsx_dev_runtime_1.jsxDEV)(Wrong, { children: "Byebye, world!" }, void 0, false, { fileName: _jsxFileName, lineNumber: 5, columnNumber: 76 }, this);
44+
//// [jsx-runtime.js]
45+
"use strict";
46+
Object.defineProperty(exports, "__esModule", { value: true });
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
//// [tests/cases/compiler/jsxNamespaceElementChildrenAttributeIgnoredWhenReactJsx.tsx] ////
2+
3+
=== /jsx.d.ts ===
4+
declare namespace JSX {
5+
>JSX : Symbol(JSX, Decl(jsx.d.ts, 0, 0))
6+
7+
interface IntrinsicElements {
8+
>IntrinsicElements : Symbol(IntrinsicElements, Decl(jsx.d.ts, 0, 23))
9+
10+
h1: { children: string }
11+
>h1 : Symbol(IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
12+
>children : Symbol(children, Decl(jsx.d.ts, 2, 9))
13+
}
14+
15+
type Element = string;
16+
>Element : Symbol(Element, Decl(jsx.d.ts, 3, 3))
17+
18+
interface ElementChildrenAttribute {
19+
>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(jsx.d.ts, 5, 24))
20+
21+
offspring: any;
22+
>offspring : Symbol(ElementChildrenAttribute.offspring, Decl(jsx.d.ts, 7, 38))
23+
}
24+
}
25+
26+
=== /test.tsx ===
27+
const Title = (props: { children: string }) => <h1>{props.children}</h1>;
28+
>Title : Symbol(Title, Decl(test.tsx, 0, 5))
29+
>props : Symbol(props, Decl(test.tsx, 0, 15))
30+
>children : Symbol(children, Decl(test.tsx, 0, 23))
31+
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
32+
>props.children : Symbol(children, Decl(test.tsx, 0, 23))
33+
>props : Symbol(props, Decl(test.tsx, 0, 15))
34+
>children : Symbol(children, Decl(test.tsx, 0, 23))
35+
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
36+
37+
<Title>Hello, world!</Title>;
38+
>Title : Symbol(Title, Decl(test.tsx, 0, 5))
39+
>Title : Symbol(Title, Decl(test.tsx, 0, 5))
40+
41+
const Wrong = (props: { offspring: string }) => <h1>{props.offspring}</h1>;
42+
>Wrong : Symbol(Wrong, Decl(test.tsx, 4, 5))
43+
>props : Symbol(props, Decl(test.tsx, 4, 15))
44+
>offspring : Symbol(offspring, Decl(test.tsx, 4, 23))
45+
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
46+
>props.offspring : Symbol(offspring, Decl(test.tsx, 4, 23))
47+
>props : Symbol(props, Decl(test.tsx, 4, 15))
48+
>offspring : Symbol(offspring, Decl(test.tsx, 4, 23))
49+
>h1 : Symbol(JSX.IntrinsicElements.h1, Decl(jsx.d.ts, 1, 31))
50+
51+
<Wrong>Byebye, world!</Wrong>
52+
>Wrong : Symbol(Wrong, Decl(test.tsx, 4, 5))
53+
>Wrong : Symbol(Wrong, Decl(test.tsx, 4, 5))
54+
55+
=== /jsx/jsx-runtime.ts ===
56+
57+
export {};
58+
=== /jsx/jsx-dev-runtime.ts ===
59+
60+
export {};
61+

0 commit comments

Comments
 (0)