Skip to content

Commit 09eb3d3

Browse files
authored
Fix/jsx global preferred over config implicit (#41476)
* Add actual baselines for a problem with global namespace being preferred over config & pragma implicit ones * Fixed an issue with global React namespace being preferred over config & pragma implicit ones * Do not try to mark JSX classic runtime symbols as used when automatic runtime is used
1 parent 6369d89 commit 09eb3d3

11 files changed

+900
-27
lines changed

src/compiler/checker.ts

+28-23
Original file line numberDiff line numberDiff line change
@@ -25193,11 +25193,13 @@ namespace ts {
2519325193
return links.jsxNamespace;
2519425194
}
2519525195
if (!links || links.jsxNamespace !== false) {
25196-
const namespaceName = getJsxNamespace(location);
25197-
let resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false);
25196+
let resolvedNamespace = getJsxNamespaceContainerForImplicitImport(location);
25197+
2519825198
if (!resolvedNamespace || resolvedNamespace === unknownSymbol) {
25199-
resolvedNamespace = getJsxNamespaceContainerForImplicitImport(location);
25199+
const namespaceName = getJsxNamespace(location);
25200+
resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false);
2520025201
}
25202+
2520125203
if (resolvedNamespace) {
2520225204
const candidate = resolveSymbol(getSymbol(getExportsOfSymbol(resolveSymbol(resolvedNamespace)), JsxNames.JSX, SymbolFlags.Namespace));
2520325205
if (candidate && candidate !== unknownSymbol) {
@@ -25420,26 +25422,29 @@ namespace ts {
2542025422
}
2542125423

2542225424
checkJsxPreconditions(node);
25423-
// The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
25424-
// And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
25425-
const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
25426-
const jsxFactoryNamespace = getJsxNamespace(node);
25427-
const jsxFactoryLocation = isNodeOpeningLikeElement ? (<JsxOpeningLikeElement>node).tagName : node;
25428-
25429-
// allow null as jsxFragmentFactory
25430-
let jsxFactorySym: Symbol | undefined;
25431-
if (!(isJsxOpeningFragment(node) && jsxFactoryNamespace === "null")) {
25432-
jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, SymbolFlags.Value, jsxFactoryRefErr, jsxFactoryNamespace, /*isUse*/ true);
25433-
}
25434-
25435-
if (jsxFactorySym) {
25436-
// Mark local symbol as referenced here because it might not have been marked
25437-
// if jsx emit was not jsxFactory as there wont be error being emitted
25438-
jsxFactorySym.isReferenced = SymbolFlags.All;
25439-
25440-
// If react/jsxFactory symbol is alias, mark it as refereced
25441-
if (jsxFactorySym.flags & SymbolFlags.Alias && !getTypeOnlyAliasDeclaration(jsxFactorySym)) {
25442-
markAliasSymbolAsReferenced(jsxFactorySym);
25425+
25426+
if (!getJsxNamespaceContainerForImplicitImport(node)) {
25427+
// The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
25428+
// And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
25429+
const jsxFactoryRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
25430+
const jsxFactoryNamespace = getJsxNamespace(node);
25431+
const jsxFactoryLocation = isNodeOpeningLikeElement ? (<JsxOpeningLikeElement>node).tagName : node;
25432+
25433+
// allow null as jsxFragmentFactory
25434+
let jsxFactorySym: Symbol | undefined;
25435+
if (!(isJsxOpeningFragment(node) && jsxFactoryNamespace === "null")) {
25436+
jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, SymbolFlags.Value, jsxFactoryRefErr, jsxFactoryNamespace, /*isUse*/ true);
25437+
}
25438+
25439+
if (jsxFactorySym) {
25440+
// Mark local symbol as referenced here because it might not have been marked
25441+
// if jsx emit was not jsxFactory as there wont be error being emitted
25442+
jsxFactorySym.isReferenced = SymbolFlags.All;
25443+
25444+
// If react/jsxFactory symbol is alias, mark it as refereced
25445+
if (jsxFactorySym.flags & SymbolFlags.Alias && !getTypeOnlyAliasDeclaration(jsxFactorySym)) {
25446+
markAliasSymbolAsReferenced(jsxFactorySym);
25447+
}
2544325448
}
2544425449
}
2544525450

tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsx).js

-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ const element = (
2121
"use strict";
2222
exports.__esModule = true;
2323
var jsx_runtime_1 = require("react/jsx-runtime");
24-
/// <reference path="react16.d.ts" />
25-
var React = require("react");
2624
function Wrapper(props) {
2725
return jsx_runtime_1.jsx("div", { children: props.children }, void 0);
2826
}

tests/baselines/reference/jsxEmptyExpressionNotCountedAsChild(jsx=react-jsxdev).js

-2
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@ const element = (
2222
exports.__esModule = true;
2323
var jsx_dev_runtime_1 = require("react/jsx-dev-runtime");
2424
var _jsxFileName = "tests/cases/compiler/jsxEmptyExpressionNotCountedAsChild.tsx";
25-
/// <reference path="react16.d.ts" />
26-
var React = require("react");
2725
function Wrapper(props) {
2826
return jsx_dev_runtime_1.jsxDEV("div", { children: props.children }, void 0, false, { fileName: _jsxFileName, lineNumber: 9, columnNumber: 11 }, this);
2927
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
//// [tests/cases/compiler/jsxNamespaceImplicitImportJSXNamespaceFromConfigPickedOverGlobalOne.tsx] ////
2+
3+
//// [index.d.ts]
4+
export = React;
5+
export as namespace React;
6+
7+
declare namespace React {}
8+
9+
declare global {
10+
namespace JSX {
11+
interface Element {}
12+
interface ElementClass {}
13+
interface ElementAttributesProperty {}
14+
interface ElementChildrenAttribute {}
15+
type LibraryManagedAttributes<C, P> = {}
16+
interface IntrinsicAttributes {}
17+
interface IntrinsicClassAttributes<T> {}
18+
interface IntrinsicElements {
19+
div: {}
20+
}
21+
}
22+
}
23+
//// [index.d.ts]
24+
export { EmotionJSX as JSX } from './jsx-namespace'
25+
26+
//// [jsx-namespace.d.ts]
27+
import 'react'
28+
29+
type WithConditionalCSSProp<P> = 'className' extends keyof P
30+
? (P extends { className?: string } ? P & { css?: string } : P)
31+
: P
32+
33+
type ReactJSXElement = JSX.Element
34+
type ReactJSXElementClass = JSX.ElementClass
35+
type ReactJSXElementAttributesProperty = JSX.ElementAttributesProperty
36+
type ReactJSXElementChildrenAttribute = JSX.ElementChildrenAttribute
37+
type ReactJSXLibraryManagedAttributes<C, P> = JSX.LibraryManagedAttributes<C, P>
38+
type ReactJSXIntrinsicAttributes = JSX.IntrinsicAttributes
39+
type ReactJSXIntrinsicClassAttributes<T> = JSX.IntrinsicClassAttributes<T>
40+
type ReactJSXIntrinsicElements = JSX.IntrinsicElements
41+
42+
export namespace EmotionJSX {
43+
interface Element extends ReactJSXElement {}
44+
interface ElementClass extends ReactJSXElementClass {}
45+
interface ElementAttributesProperty
46+
extends ReactJSXElementAttributesProperty {}
47+
interface ElementChildrenAttribute extends ReactJSXElementChildrenAttribute {}
48+
49+
type LibraryManagedAttributes<C, P> = WithConditionalCSSProp<P> &
50+
ReactJSXLibraryManagedAttributes<C, P>
51+
52+
interface IntrinsicAttributes extends ReactJSXIntrinsicAttributes {}
53+
interface IntrinsicClassAttributes<T>
54+
extends ReactJSXIntrinsicClassAttributes<T> {}
55+
56+
type IntrinsicElements = {
57+
[K in keyof ReactJSXIntrinsicElements]: ReactJSXIntrinsicElements[K] & {
58+
css?: string
59+
}
60+
}
61+
}
62+
63+
//// [index.tsx]
64+
export const Comp = () => <div css="color: hotpink;"></div>;
65+
66+
67+
//// [index.js]
68+
"use strict";
69+
exports.__esModule = true;
70+
exports.Comp = void 0;
71+
var jsx_runtime_1 = require("@emotion/react/jsx-runtime");
72+
var Comp = function () { return jsx_runtime_1.jsx("div", { css: "color: hotpink;" }, void 0); };
73+
exports.Comp = Comp;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
=== /node_modules/react/index.d.ts ===
2+
export = React;
3+
>React : Symbol(React, Decl(index.d.ts, 1, 26))
4+
5+
export as namespace React;
6+
>React : Symbol(React, Decl(index.d.ts, 0, 15))
7+
8+
declare namespace React {}
9+
>React : Symbol(React, Decl(index.d.ts, 1, 26))
10+
11+
declare global {
12+
>global : Symbol(global, Decl(index.d.ts, 3, 26))
13+
14+
namespace JSX {
15+
>JSX : Symbol(JSX, Decl(index.d.ts, 5, 16))
16+
17+
interface Element {}
18+
>Element : Symbol(Element, Decl(index.d.ts, 6, 17))
19+
20+
interface ElementClass {}
21+
>ElementClass : Symbol(ElementClass, Decl(index.d.ts, 7, 24))
22+
23+
interface ElementAttributesProperty {}
24+
>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(index.d.ts, 8, 29))
25+
26+
interface ElementChildrenAttribute {}
27+
>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(index.d.ts, 9, 42))
28+
29+
type LibraryManagedAttributes<C, P> = {}
30+
>LibraryManagedAttributes : Symbol(LibraryManagedAttributes, Decl(index.d.ts, 10, 41))
31+
>C : Symbol(C, Decl(index.d.ts, 11, 34))
32+
>P : Symbol(P, Decl(index.d.ts, 11, 36))
33+
34+
interface IntrinsicAttributes {}
35+
>IntrinsicAttributes : Symbol(IntrinsicAttributes, Decl(index.d.ts, 11, 44))
36+
37+
interface IntrinsicClassAttributes<T> {}
38+
>IntrinsicClassAttributes : Symbol(IntrinsicClassAttributes, Decl(index.d.ts, 12, 36))
39+
>T : Symbol(T, Decl(index.d.ts, 13, 39))
40+
41+
interface IntrinsicElements {
42+
>IntrinsicElements : Symbol(IntrinsicElements, Decl(index.d.ts, 13, 44))
43+
44+
div: {}
45+
>div : Symbol(IntrinsicElements.div, Decl(index.d.ts, 14, 33))
46+
}
47+
}
48+
}
49+
=== /node_modules/@emotion/react/jsx-runtime/index.d.ts ===
50+
export { EmotionJSX as JSX } from './jsx-namespace'
51+
>EmotionJSX : Symbol(EmotionJSX, Decl(jsx-namespace.d.ts, 13, 54))
52+
>JSX : Symbol(JSX, Decl(index.d.ts, 0, 8))
53+
54+
=== /node_modules/@emotion/react/jsx-runtime/jsx-namespace.d.ts ===
55+
import 'react'
56+
57+
type WithConditionalCSSProp<P> = 'className' extends keyof P
58+
>WithConditionalCSSProp : Symbol(WithConditionalCSSProp, Decl(jsx-namespace.d.ts, 0, 14))
59+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 2, 28))
60+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 2, 28))
61+
62+
? (P extends { className?: string } ? P & { css?: string } : P)
63+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 2, 28))
64+
>className : Symbol(className, Decl(jsx-namespace.d.ts, 3, 16))
65+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 2, 28))
66+
>css : Symbol(css, Decl(jsx-namespace.d.ts, 3, 45))
67+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 2, 28))
68+
69+
: P
70+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 2, 28))
71+
72+
type ReactJSXElement = JSX.Element
73+
>ReactJSXElement : Symbol(ReactJSXElement, Decl(jsx-namespace.d.ts, 4, 5))
74+
>JSX : Symbol(JSX, Decl(index.d.ts, 5, 16))
75+
>Element : Symbol(JSX.Element, Decl(index.d.ts, 6, 17))
76+
77+
type ReactJSXElementClass = JSX.ElementClass
78+
>ReactJSXElementClass : Symbol(ReactJSXElementClass, Decl(jsx-namespace.d.ts, 6, 34))
79+
>JSX : Symbol(JSX, Decl(index.d.ts, 5, 16))
80+
>ElementClass : Symbol(JSX.ElementClass, Decl(index.d.ts, 7, 24))
81+
82+
type ReactJSXElementAttributesProperty = JSX.ElementAttributesProperty
83+
>ReactJSXElementAttributesProperty : Symbol(ReactJSXElementAttributesProperty, Decl(jsx-namespace.d.ts, 7, 44))
84+
>JSX : Symbol(JSX, Decl(index.d.ts, 5, 16))
85+
>ElementAttributesProperty : Symbol(JSX.ElementAttributesProperty, Decl(index.d.ts, 8, 29))
86+
87+
type ReactJSXElementChildrenAttribute = JSX.ElementChildrenAttribute
88+
>ReactJSXElementChildrenAttribute : Symbol(ReactJSXElementChildrenAttribute, Decl(jsx-namespace.d.ts, 8, 70))
89+
>JSX : Symbol(JSX, Decl(index.d.ts, 5, 16))
90+
>ElementChildrenAttribute : Symbol(JSX.ElementChildrenAttribute, Decl(index.d.ts, 9, 42))
91+
92+
type ReactJSXLibraryManagedAttributes<C, P> = JSX.LibraryManagedAttributes<C, P>
93+
>ReactJSXLibraryManagedAttributes : Symbol(ReactJSXLibraryManagedAttributes, Decl(jsx-namespace.d.ts, 9, 68))
94+
>C : Symbol(C, Decl(jsx-namespace.d.ts, 10, 38))
95+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 10, 40))
96+
>JSX : Symbol(JSX, Decl(index.d.ts, 5, 16))
97+
>LibraryManagedAttributes : Symbol(JSX.LibraryManagedAttributes, Decl(index.d.ts, 10, 41))
98+
>C : Symbol(C, Decl(jsx-namespace.d.ts, 10, 38))
99+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 10, 40))
100+
101+
type ReactJSXIntrinsicAttributes = JSX.IntrinsicAttributes
102+
>ReactJSXIntrinsicAttributes : Symbol(ReactJSXIntrinsicAttributes, Decl(jsx-namespace.d.ts, 10, 80))
103+
>JSX : Symbol(JSX, Decl(index.d.ts, 5, 16))
104+
>IntrinsicAttributes : Symbol(JSX.IntrinsicAttributes, Decl(index.d.ts, 11, 44))
105+
106+
type ReactJSXIntrinsicClassAttributes<T> = JSX.IntrinsicClassAttributes<T>
107+
>ReactJSXIntrinsicClassAttributes : Symbol(ReactJSXIntrinsicClassAttributes, Decl(jsx-namespace.d.ts, 11, 58))
108+
>T : Symbol(T, Decl(jsx-namespace.d.ts, 12, 38))
109+
>JSX : Symbol(JSX, Decl(index.d.ts, 5, 16))
110+
>IntrinsicClassAttributes : Symbol(JSX.IntrinsicClassAttributes, Decl(index.d.ts, 12, 36))
111+
>T : Symbol(T, Decl(jsx-namespace.d.ts, 12, 38))
112+
113+
type ReactJSXIntrinsicElements = JSX.IntrinsicElements
114+
>ReactJSXIntrinsicElements : Symbol(ReactJSXIntrinsicElements, Decl(jsx-namespace.d.ts, 12, 74))
115+
>JSX : Symbol(JSX, Decl(index.d.ts, 5, 16))
116+
>IntrinsicElements : Symbol(JSX.IntrinsicElements, Decl(index.d.ts, 13, 44))
117+
118+
export namespace EmotionJSX {
119+
>EmotionJSX : Symbol(EmotionJSX, Decl(jsx-namespace.d.ts, 13, 54))
120+
121+
interface Element extends ReactJSXElement {}
122+
>Element : Symbol(Element, Decl(jsx-namespace.d.ts, 15, 29))
123+
>ReactJSXElement : Symbol(ReactJSXElement, Decl(jsx-namespace.d.ts, 4, 5))
124+
125+
interface ElementClass extends ReactJSXElementClass {}
126+
>ElementClass : Symbol(ElementClass, Decl(jsx-namespace.d.ts, 16, 46))
127+
>ReactJSXElementClass : Symbol(ReactJSXElementClass, Decl(jsx-namespace.d.ts, 6, 34))
128+
129+
interface ElementAttributesProperty
130+
>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(jsx-namespace.d.ts, 17, 56))
131+
132+
extends ReactJSXElementAttributesProperty {}
133+
>ReactJSXElementAttributesProperty : Symbol(ReactJSXElementAttributesProperty, Decl(jsx-namespace.d.ts, 7, 44))
134+
135+
interface ElementChildrenAttribute extends ReactJSXElementChildrenAttribute {}
136+
>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(jsx-namespace.d.ts, 19, 48))
137+
>ReactJSXElementChildrenAttribute : Symbol(ReactJSXElementChildrenAttribute, Decl(jsx-namespace.d.ts, 8, 70))
138+
139+
type LibraryManagedAttributes<C, P> = WithConditionalCSSProp<P> &
140+
>LibraryManagedAttributes : Symbol(LibraryManagedAttributes, Decl(jsx-namespace.d.ts, 20, 80))
141+
>C : Symbol(C, Decl(jsx-namespace.d.ts, 22, 32))
142+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 22, 34))
143+
>WithConditionalCSSProp : Symbol(WithConditionalCSSProp, Decl(jsx-namespace.d.ts, 0, 14))
144+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 22, 34))
145+
146+
ReactJSXLibraryManagedAttributes<C, P>
147+
>ReactJSXLibraryManagedAttributes : Symbol(ReactJSXLibraryManagedAttributes, Decl(jsx-namespace.d.ts, 9, 68))
148+
>C : Symbol(C, Decl(jsx-namespace.d.ts, 22, 32))
149+
>P : Symbol(P, Decl(jsx-namespace.d.ts, 22, 34))
150+
151+
interface IntrinsicAttributes extends ReactJSXIntrinsicAttributes {}
152+
>IntrinsicAttributes : Symbol(IntrinsicAttributes, Decl(jsx-namespace.d.ts, 23, 42))
153+
>ReactJSXIntrinsicAttributes : Symbol(ReactJSXIntrinsicAttributes, Decl(jsx-namespace.d.ts, 10, 80))
154+
155+
interface IntrinsicClassAttributes<T>
156+
>IntrinsicClassAttributes : Symbol(IntrinsicClassAttributes, Decl(jsx-namespace.d.ts, 25, 70))
157+
>T : Symbol(T, Decl(jsx-namespace.d.ts, 26, 37))
158+
159+
extends ReactJSXIntrinsicClassAttributes<T> {}
160+
>ReactJSXIntrinsicClassAttributes : Symbol(ReactJSXIntrinsicClassAttributes, Decl(jsx-namespace.d.ts, 11, 58))
161+
>T : Symbol(T, Decl(jsx-namespace.d.ts, 26, 37))
162+
163+
type IntrinsicElements = {
164+
>IntrinsicElements : Symbol(IntrinsicElements, Decl(jsx-namespace.d.ts, 27, 50))
165+
166+
[K in keyof ReactJSXIntrinsicElements]: ReactJSXIntrinsicElements[K] & {
167+
>K : Symbol(K, Decl(jsx-namespace.d.ts, 30, 5))
168+
>ReactJSXIntrinsicElements : Symbol(ReactJSXIntrinsicElements, Decl(jsx-namespace.d.ts, 12, 74))
169+
>ReactJSXIntrinsicElements : Symbol(ReactJSXIntrinsicElements, Decl(jsx-namespace.d.ts, 12, 74))
170+
>K : Symbol(K, Decl(jsx-namespace.d.ts, 30, 5))
171+
172+
css?: string
173+
>css : Symbol(css, Decl(jsx-namespace.d.ts, 30, 76))
174+
}
175+
}
176+
}
177+
178+
=== /index.tsx ===
179+
export const Comp = () => <div css="color: hotpink;"></div>;
180+
>Comp : Symbol(Comp, Decl(index.tsx, 0, 12))
181+
>div : Symbol(div, Decl(index.d.ts, 14, 33))
182+
>css : Symbol(css, Decl(index.tsx, 0, 30))
183+
>div : Symbol(div, Decl(index.d.ts, 14, 33))
184+

0 commit comments

Comments
 (0)