fix fragment resolving behavior with jsx: preserve and jsxFragmentFactory: null (#60122)

This commit is contained in:
Isabel Duan
2024-10-04 11:47:59 -07:00
committed by GitHub
parent ca18009b8b
commit b845fd2434
7 changed files with 23 additions and 102 deletions
+10 -6
View File
@@ -29873,10 +29873,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const jsxFactoryNamespace = getJsxNamespace(node);
const jsxFactoryLocation = isJsxOpeningLikeElement(node) ? node.tagName : node;
// allow null as jsxFragmentFactory
// #38720/60122, allow null as jsxFragmentFactory
let jsxFactorySym: Symbol | undefined;
if (!(isJsxOpeningFragment(node) && jsxFactoryNamespace === "null")) {
jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
jsxFactorySym = resolveName(jsxFactoryLocation, jsxFactoryNamespace, compilerOptions.jsx === JsxEmit.Preserve ? SymbolFlags.Value & ~SymbolFlags.Enum : SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
}
if (jsxFactorySym) {
@@ -29890,12 +29890,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
// For JsxFragment, mark jsx pragma as referenced via resolveName
// if JsxFragment, additionally mark jsx pragma as referenced, since `getJsxNamespace` above would have resolved to only the fragment factory if they are distinct
if (isJsxOpeningFragment(node)) {
const file = getSourceFileOfNode(node);
const localJsxNamespace = getLocalJsxNamespace(file);
if (localJsxNamespace) {
resolveName(jsxFactoryLocation, localJsxNamespace, SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
resolveName(jsxFactoryLocation, localJsxNamespace, compilerOptions.jsx === JsxEmit.Preserve ? SymbolFlags.Value & ~SymbolFlags.Enum : SymbolFlags.Value, jsxFactoryRefErr, /*isUse*/ true);
}
}
}
@@ -32918,7 +32918,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
checkJsxChildren(node);
return getJsxElementTypeAt(node) || anyType;
const jsxElementType = getJsxElementTypeAt(node);
return isErrorType(jsxElementType) ? anyType : jsxElementType;
}
function isHyphenatedJsxName(name: string | __String) {
@@ -36643,9 +36644,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (sourceFileLinks.jsxFragmentType !== undefined) return sourceFileLinks.jsxFragmentType;
const jsxFragmentFactoryName = getJsxNamespace(node);
// #38720/60122, allow null as jsxFragmentFactory
if (jsxFragmentFactoryName === "null") return sourceFileLinks.jsxFragmentType = anyType;
const jsxFactoryRefErr = diagnostics ? Diagnostics.Using_JSX_fragments_requires_fragment_factory_0_to_be_in_scope_but_it_could_not_be_found : undefined;
const jsxFactorySymbol = getJsxNamespaceContainerForImplicitImport(node) ??
resolveName(node, jsxFragmentFactoryName, SymbolFlags.Value, /*nameNotFoundMessage*/ jsxFactoryRefErr, /*isUse*/ true);
resolveName(node, jsxFragmentFactoryName, compilerOptions.jsx === JsxEmit.Preserve ? SymbolFlags.Value & ~SymbolFlags.Enum : SymbolFlags.Value, /*nameNotFoundMessage*/ jsxFactoryRefErr, /*isUse*/ true);
if (jsxFactorySymbol === undefined) return sourceFileLinks.jsxFragmentType = errorType;
if (jsxFactorySymbol.escapedName === ReactNames.Fragment) return sourceFileLinks.jsxFragmentType = getTypeOfSymbol(jsxFactorySymbol);