From 488397f0ebf8430433cc886d6bb901e84a9529d6 Mon Sep 17 00:00:00 2001
From: Wesley Wigham
Date: Mon, 26 Feb 2018 17:49:26 -0800
Subject: [PATCH] Lookup JSX namespace within factory function
---
src/compiler/checker.ts | 169 +++-----
src/compiler/types.ts | 2 +-
src/services/completions.ts | 2 +-
.../reference/api/tsserverlibrary.d.ts | 2 +-
tests/baselines/reference/api/typescript.d.ts | 2 +-
...sxFactoryDeclarationsLocalTypes.errors.txt | 129 ++++++
.../inlineJsxFactoryDeclarationsLocalTypes.js | 164 ++++++++
...neJsxFactoryDeclarationsLocalTypes.symbols | 346 +++++++++++++++
...lineJsxFactoryDeclarationsLocalTypes.types | 394 ++++++++++++++++++
...xFactoryLocalTypeGlobalFallback.errors.txt | 51 +++
...inlineJsxFactoryLocalTypeGlobalFallback.js | 61 +++
...eJsxFactoryLocalTypeGlobalFallback.symbols | 107 +++++
...ineJsxFactoryLocalTypeGlobalFallback.types | 110 +++++
.../tsxElementResolution16.errors.txt | 5 +-
...inlineJsxFactoryDeclarationsLocalTypes.tsx | 86 ++++
...nlineJsxFactoryLocalTypeGlobalFallback.tsx | 44 ++
16 files changed, 1560 insertions(+), 114 deletions(-)
create mode 100644 tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt
create mode 100644 tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js
create mode 100644 tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.symbols
create mode 100644 tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.types
create mode 100644 tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt
create mode 100644 tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.js
create mode 100644 tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.symbols
create mode 100644 tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.types
create mode 100644 tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx
create mode 100644 tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx
diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts
index 63b8d18c451f6..d6aa4760450e7 100644
--- a/src/compiler/checker.ts
+++ b/src/compiler/checker.ts
@@ -417,9 +417,6 @@ namespace ts {
let deferredGlobalAsyncIteratorType: GenericType;
let deferredGlobalAsyncIterableIteratorType: GenericType;
let deferredGlobalTemplateStringsArrayType: ObjectType;
- let deferredJsxElementClassType: Type;
- let deferredJsxElementType: Type;
- let deferredJsxStatelessElementType: Type;
let deferredNodes: Node[];
let deferredUnusedIdentifierNodes: Node[];
@@ -545,13 +542,6 @@ namespace ts {
let _jsxNamespace: __String;
let _jsxFactoryEntity: EntityName;
- let _jsxElementPropertiesName: __String;
- let _hasComputedJsxElementPropertiesName = false;
- let _jsxElementChildrenPropertyName: __String;
- let _hasComputedJsxElementChildrenPropertyName = false;
-
- /** Things we lazy load from the JSX namespace */
- const jsxTypes = createUnderscoreEscapedMap();
const subtypeRelation = createMap();
const assignableRelation = createMap();
@@ -7521,16 +7511,6 @@ namespace ts {
return symbol && getTypeOfGlobalSymbol(symbol, arity);
}
- /**
- * Returns a type that is inside a namespace at the global scope, e.g.
- * getExportedTypeFromNamespace('JSX', 'Element') returns the JSX.Element type
- */
- function getExportedTypeFromNamespace(namespace: __String, name: __String): Type {
- const namespaceSymbol = getGlobalSymbol(namespace, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined);
- const typeSymbol = namespaceSymbol && getSymbol(namespaceSymbol.exports, name, SymbolFlags.Type);
- return typeSymbol && getDeclaredTypeOfSymbol(typeSymbol);
- }
-
/**
* Instantiates a global type that is generic with some element type, and returns that instantiation.
*/
@@ -14345,7 +14325,7 @@ namespace ts {
function getContextualTypeForChildJsxExpression(node: JsxElement) {
const attributesType = getApparentTypeOfContextualType(node.openingElement.tagName);
// JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
- const jsxChildrenPropertyName = getJsxElementChildrenPropertyName();
+ const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceForLocation(node));
return attributesType && !isTypeAny(attributesType) && jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfContextualType(attributesType, jsxChildrenPropertyName) : undefined;
}
@@ -14499,18 +14479,10 @@ namespace ts {
}
const isJs = isInJavaScriptFile(node);
- return mapType(valueType, isJs ? getJsxSignaturesParameterTypesJs : getJsxSignaturesParameterTypes);
- }
-
- function getJsxSignaturesParameterTypes(valueType: Type) {
- return getJsxSignaturesParameterTypesInternal(valueType, /*isJs*/ false);
+ return mapType(valueType, t => getJsxSignaturesParameterTypes(t, isJs, node));
}
- function getJsxSignaturesParameterTypesJs(valueType: Type) {
- return getJsxSignaturesParameterTypesInternal(valueType, /*isJs*/ true);
- }
-
- function getJsxSignaturesParameterTypesInternal(valueType: Type, isJs: boolean) {
+ function getJsxSignaturesParameterTypes(valueType: Type, isJs: boolean, context: Node) {
// If the elemType is a string type, we have to return anyType to prevent an error downstream as we will try to find construct or call signature of the type
if (valueType.flags & TypeFlags.String) {
return anyType;
@@ -14520,7 +14492,7 @@ namespace ts {
// For example:
// var CustomTag: "h1" = "h1";
// Hello World
- const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
+ const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, context);
if (intrinsicElementsType !== unknownType) {
const stringLiteralTypeName = (valueType).value;
const intrinsicProp = getPropertyOfType(intrinsicElementsType, escapeLeadingUnderscores(stringLiteralTypeName));
@@ -14548,24 +14520,24 @@ namespace ts {
}
}
- return getUnionType(map(signatures, ctor ? isJs ? getJsxPropsTypeFromConstructSignatureJs : getJsxPropsTypeFromConstructSignature : getJsxPropsTypeFromCallSignature), UnionReduction.None);
+ return getUnionType(map(signatures, ctor ? t => getJsxPropsTypeFromConstructSignature(t, isJs, context) : t => getJsxPropsTypeFromCallSignature(t, context)), UnionReduction.None);
}
- function getJsxPropsTypeFromCallSignature(sig: Signature) {
+ function getJsxPropsTypeFromCallSignature(sig: Signature, context: Node) {
let propsType = getTypeOfFirstParameterOfSignature(sig);
- const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes);
+ const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
if (intrinsicAttribs !== unknownType) {
propsType = intersectTypes(intrinsicAttribs, propsType);
}
return propsType;
}
- function getJsxPropsTypeFromClassType(hostClassType: Type, isJs: boolean) {
+ function getJsxPropsTypeFromClassType(hostClassType: Type, isJs: boolean, context: Node) {
if (isTypeAny(hostClassType)) {
return hostClassType;
}
- const propsName = getJsxElementPropertiesName();
+ const propsName = getJsxElementPropertiesName(getJsxNamespaceForLocation(context));
if (propsName === undefined) {
// There is no type ElementAttributesProperty, return 'any'
return anyType;
@@ -14588,7 +14560,7 @@ namespace ts {
else {
// Normal case -- add in IntrinsicClassElements and IntrinsicElements
let apparentAttributesType = attributesType;
- const intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes);
+ const intrinsicClassAttribs = getJsxType(JsxNames.IntrinsicClassAttributes, context);
if (intrinsicClassAttribs !== unknownType) {
const typeParams = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(intrinsicClassAttribs.symbol);
apparentAttributesType = intersectTypes(
@@ -14599,7 +14571,7 @@ namespace ts {
);
}
- const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes);
+ const intrinsicAttribs = getJsxType(JsxNames.IntrinsicAttributes, context);
if (intrinsicAttribs !== unknownType) {
apparentAttributesType = intersectTypes(intrinsicAttribs, apparentAttributesType);
}
@@ -14609,20 +14581,12 @@ namespace ts {
}
}
- function getJsxPropsTypeFromConstructSignatureJs(sig: Signature) {
- return getJsxPropsTypeFromConstructSignatureInternal(sig, /*isJs*/ true);
- }
-
- function getJsxPropsTypeFromConstructSignature(sig: Signature) {
- return getJsxPropsTypeFromConstructSignatureInternal(sig, /*isJs*/ false);
- }
-
- function getJsxPropsTypeFromConstructSignatureInternal(sig: Signature, isJs: boolean) {
+ function getJsxPropsTypeFromConstructSignature(sig: Signature, isJs: boolean, context: Node) {
const hostClassType = getReturnTypeOfSignature(sig);
if (hostClassType) {
- return getJsxPropsTypeFromClassType(hostClassType, isJs);
+ return getJsxPropsTypeFromClassType(hostClassType, isJs, context);
}
- return getJsxPropsTypeFromCallSignature(sig);
+ return getJsxPropsTypeFromCallSignature(sig, context);
}
@@ -15077,7 +15041,7 @@ namespace ts {
function checkJsxSelfClosingElement(node: JsxSelfClosingElement, checkMode: CheckMode): Type {
checkJsxOpeningLikeElementOrOpeningFragment(node, checkMode);
- return getJsxGlobalElementType() || anyType;
+ return getJsxElementTypeAt(node) || anyType;
}
function checkJsxElement(node: JsxElement, checkMode: CheckMode): Type {
@@ -15092,7 +15056,7 @@ namespace ts {
checkExpression(node.closingElement.tagName);
}
- return getJsxGlobalElementType() || anyType;
+ return getJsxElementTypeAt(node) || anyType;
}
function checkJsxFragment(node: JsxFragment, checkMode: CheckMode): Type {
@@ -15104,7 +15068,7 @@ namespace ts {
: Diagnostics.JSX_fragment_is_not_supported_when_using_an_inline_JSX_factory_pragma);
}
- return getJsxGlobalElementType() || anyType;
+ return getJsxElementTypeAt(node) || anyType;
}
/**
@@ -15153,7 +15117,7 @@ namespace ts {
let hasSpreadAnyType = false;
let typeToIntersect: Type;
let explicitlySpecifyChildrenAttribute = false;
- const jsxChildrenPropertyName = getJsxElementChildrenPropertyName();
+ const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceForLocation(openingLikeElement));
for (const attributeDecl of attributes.properties) {
const member = attributeDecl.symbol;
@@ -15269,12 +15233,11 @@ namespace ts {
return createJsxAttributesTypeFromAttributesProperty(node.parent, checkMode);
}
- function getJsxType(name: __String) {
- let jsxType = jsxTypes.get(name);
- if (jsxType === undefined) {
- jsxTypes.set(name, jsxType = getExportedTypeFromNamespace(JsxNames.JSX, name) || unknownType);
- }
- return jsxType;
+ function getJsxType(name: __String, location: Node) {
+ const namespace = getJsxNamespaceForLocation(location);
+ const exports = namespace && getExportsOfSymbol(namespace);
+ const typeSymbol = exports && getSymbol(exports, name, SymbolFlags.Type);
+ return typeSymbol ? getDeclaredTypeOfSymbol(typeSymbol) : unknownType;
}
/**
@@ -15286,7 +15249,7 @@ namespace ts {
function getIntrinsicTagSymbol(node: JsxOpeningLikeElement | JsxClosingElement): Symbol {
const links = getNodeLinks(node);
if (!links.resolvedSymbol) {
- const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
+ const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, node);
if (intrinsicElementsType !== unknownType) {
// Property case
if (!isIdentifier(node.tagName)) throw Debug.fail();
@@ -15358,6 +15321,19 @@ namespace ts {
return getUnionType(map(instantiatedSignatures, getReturnTypeOfSignature), UnionReduction.Subtype);
}
+ function getJsxNamespaceForLocation(location: Node) {
+ const namespaceName = getJsxNamespace(location);
+ const resolvedNamespace = resolveName(location, namespaceName, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined, namespaceName, /*isUse*/ false);
+ if (resolvedNamespace) {
+ const candidate = getSymbol(getExportsOfSymbol(resolveSymbol(resolvedNamespace)), JsxNames.JSX, SymbolFlags.Namespace);
+ if (candidate) {
+ return candidate;
+ }
+ }
+ // JSX global fallback
+ return getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined);
+ }
+
/**
* Look into JSX namespace and then look for container with matching name as nameOfAttribPropContainer.
* Get a single property from that container if existed. Report an error if there are more than one property.
@@ -15365,9 +15341,7 @@ namespace ts {
* @param nameOfAttribPropContainer a string of value JsxNames.ElementAttributesPropertyNameContainer or JsxNames.ElementChildrenAttributeNameContainer
* if other string is given or the container doesn't exist, return undefined.
*/
- function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: __String): __String {
- // JSX
- const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined);
+ function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: __String, jsxNamespace: Symbol): __String {
// JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol]
const jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, SymbolFlags.Type);
// JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type]
@@ -15397,22 +15371,12 @@ namespace ts {
/// non-intrinsic elements' attributes type is 'any'),
/// or '' if it has 0 properties (which means every
/// non-intrinsic elements' attributes type is the element instance type)
- function getJsxElementPropertiesName() {
- if (!_hasComputedJsxElementPropertiesName) {
- _hasComputedJsxElementPropertiesName = true;
- _jsxElementPropertiesName = getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer);
- }
-
- return _jsxElementPropertiesName;
+ function getJsxElementPropertiesName(jsxNamespace: Symbol) {
+ return getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer, jsxNamespace);
}
- function getJsxElementChildrenPropertyName(): __String {
- if (!_hasComputedJsxElementChildrenPropertyName) {
- _hasComputedJsxElementChildrenPropertyName = true;
- _jsxElementChildrenPropertyName = getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer);
- }
-
- return _jsxElementChildrenPropertyName;
+ function getJsxElementChildrenPropertyName(jsxNamespace: Symbol): __String {
+ return getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer, jsxNamespace);
}
function getApparentTypeOfJsxPropsType(propsType: Type): Type {
@@ -15442,7 +15406,7 @@ namespace ts {
function defaultTryGetJsxStatelessFunctionAttributesType(openingLikeElement: JsxOpeningLikeElement, elementType: Type, elemInstanceType: Type, elementClassType?: Type): Type {
Debug.assert(!(elementType.flags & TypeFlags.Union));
if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) {
- const jsxStatelessElementType = getJsxGlobalStatelessElementType();
+ const jsxStatelessElementType = getJsxStatelessElementTypeAt(openingLikeElement);
if (jsxStatelessElementType) {
// We don't call getResolvedSignature here because we have already resolve the type of JSX Element.
const callSignature = getResolvedJsxStatelessFunctionSignature(openingLikeElement, elementType, /*candidatesOutArray*/ undefined);
@@ -15452,7 +15416,7 @@ namespace ts {
paramType = getApparentTypeOfJsxPropsType(paramType);
if (callReturnType && isTypeAssignableTo(callReturnType, jsxStatelessElementType)) {
// Intersect in JSX.IntrinsicAttributes if it exists
- const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
+ const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, openingLikeElement);
if (intrinsicAttributes !== unknownType) {
paramType = intersectTypes(intrinsicAttributes, paramType);
}
@@ -15478,7 +15442,7 @@ namespace ts {
Debug.assert(!(elementType.flags & TypeFlags.Union));
if (!elementClassType || !isTypeAssignableTo(elemInstanceType, elementClassType)) {
// Is this is a stateless function component? See if its single signature's return type is assignable to the JSX Element Type
- const jsxStatelessElementType = getJsxGlobalStatelessElementType();
+ const jsxStatelessElementType = getJsxStatelessElementTypeAt(openingLikeElement);
if (jsxStatelessElementType) {
// We don't call getResolvedSignature because here we have already resolve the type of JSX Element.
const candidatesOutArray: Signature[] = [];
@@ -15511,7 +15475,7 @@ namespace ts {
result = allMatchingAttributesType;
}
// Intersect in JSX.IntrinsicAttributes if it exists
- const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes);
+ const intrinsicAttributes = getJsxType(JsxNames.IntrinsicAttributes, openingLikeElement);
if (intrinsicAttributes !== unknownType) {
result = intersectTypes(intrinsicAttributes, result);
}
@@ -15560,7 +15524,7 @@ namespace ts {
// For example:
// var CustomTag: "h1" = "h1";
// Hello World
- const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements);
+ const intrinsicElementsType = getJsxType(JsxNames.IntrinsicElements, openingLikeElement);
if (intrinsicElementsType !== unknownType) {
const stringLiteralTypeName = (elementType).value;
const intrinsicProp = getPropertyOfType(intrinsicElementsType, escapeLeadingUnderscores(stringLiteralTypeName));
@@ -15595,7 +15559,7 @@ namespace ts {
checkTypeRelatedTo(elemInstanceType, elementClassType, assignableRelation, openingLikeElement, Diagnostics.JSX_element_type_0_is_not_a_constructor_function_for_JSX_elements);
}
- return getJsxPropsTypeFromClassType(elemInstanceType, isInJavaScriptFile(openingLikeElement));
+ return getJsxPropsTypeFromClassType(elemInstanceType, isInJavaScriptFile(openingLikeElement), openingLikeElement);
}
/**
@@ -15628,7 +15592,7 @@ namespace ts {
* @param shouldIncludeAllStatelessAttributesType a boolean value used by language service to get all possible attributes type from an overload stateless function component
*/
function getCustomJsxElementAttributesType(node: JsxOpeningLikeElement, shouldIncludeAllStatelessAttributesType: boolean): Type {
- return resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, checkExpression(node.tagName), getJsxGlobalElementClassType());
+ return resolveCustomJsxElementAttributesType(node, shouldIncludeAllStatelessAttributesType, checkExpression(node.tagName), getJsxElementClassTypeAt(node));
}
/**
@@ -15672,35 +15636,28 @@ namespace ts {
return prop || unknownSymbol;
}
- function getJsxGlobalElementClassType(): Type {
- if (!deferredJsxElementClassType) {
- deferredJsxElementClassType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.ElementClass);
- }
- return deferredJsxElementClassType;
+ function getJsxElementClassTypeAt(location: Node): Type {
+ const type = getJsxType(JsxNames.ElementClass, location);
+ if (type === unknownType) return undefined;
+ return type;
}
- function getJsxGlobalElementType(): Type {
- if (!deferredJsxElementType) {
- deferredJsxElementType = getExportedTypeFromNamespace(JsxNames.JSX, JsxNames.Element);
- }
- return deferredJsxElementType;
+ function getJsxElementTypeAt(location: Node): Type {
+ return getJsxType(JsxNames.Element, location);
}
- function getJsxGlobalStatelessElementType(): Type {
- if (!deferredJsxStatelessElementType) {
- const jsxElementType = getJsxGlobalElementType();
- if (jsxElementType) {
- deferredJsxStatelessElementType = getUnionType([jsxElementType, nullType]);
- }
+ function getJsxStatelessElementTypeAt(location: Node): Type {
+ const jsxElementType = getJsxElementTypeAt(location);
+ if (jsxElementType) {
+ return getUnionType([jsxElementType, nullType]);
}
- return deferredJsxStatelessElementType;
}
/**
* Returns all the properties of the Jsx.IntrinsicElements interface
*/
- function getJsxIntrinsicTagNames(): Symbol[] {
- const intrinsics = getJsxType(JsxNames.IntrinsicElements);
+ function getJsxIntrinsicTagNames(location: Node): Symbol[] {
+ const intrinsics = getJsxType(JsxNames.IntrinsicElements, location);
return intrinsics ? getPropertiesOfType(intrinsics) : emptyArray;
}
@@ -15710,7 +15667,7 @@ namespace ts {
error(errorNode, Diagnostics.Cannot_use_JSX_unless_the_jsx_flag_is_provided);
}
- if (getJsxGlobalElementType() === undefined) {
+ if (getJsxElementTypeAt(errorNode) === undefined) {
if (noImplicitAny) {
error(errorNode, Diagnostics.JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist);
}
@@ -15810,7 +15767,7 @@ namespace ts {
// If the targetAttributesType is an emptyObjectType, indicating that there is no property named 'props' on this instance type.
// but there exists a sourceAttributesType, we need to explicitly give an error as normal assignability check allow excess properties and will pass.
if (targetAttributesType === emptyObjectType && (isTypeAny(sourceAttributesType) || getPropertiesOfType(sourceAttributesType).length > 0)) {
- error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, unescapeLeadingUnderscores(getJsxElementPropertiesName()));
+ error(openingLikeElement, Diagnostics.JSX_element_class_does_not_support_attributes_because_it_does_not_have_a_0_property, unescapeLeadingUnderscores(getJsxElementPropertiesName(getJsxNamespaceForLocation(openingLikeElement))));
}
else {
// Check if sourceAttributesType assignable to targetAttributesType though this check will allow excess properties
diff --git a/src/compiler/types.ts b/src/compiler/types.ts
index 6631c66f0eb3c..e4dd66a460aa4 100644
--- a/src/compiler/types.ts
+++ b/src/compiler/types.ts
@@ -2871,7 +2871,7 @@ namespace ts {
/* @internal */ getExportsAndPropertiesOfModule(moduleSymbol: Symbol): Symbol[];
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined;
- getJsxIntrinsicTagNames(): Symbol[];
+ getJsxIntrinsicTagNames(location: Node): Symbol[];
isOptionalParameter(node: ParameterDeclaration): boolean;
getAmbientModules(): Symbol[];
diff --git a/src/services/completions.ts b/src/services/completions.ts
index d07c2f494dab4..f2e3df4bc4a8a 100644
--- a/src/services/completions.ts
+++ b/src/services/completions.ts
@@ -943,7 +943,7 @@ namespace ts.Completions {
getTypeScriptMemberSymbols();
}
else if (isRightOfOpenTag) {
- const tagSymbols = Debug.assertEachDefined(typeChecker.getJsxIntrinsicTagNames(), "getJsxIntrinsicTagNames() should all be defined");
+ const tagSymbols = Debug.assertEachDefined(typeChecker.getJsxIntrinsicTagNames(location), "getJsxIntrinsicTagNames() should all be defined");
if (tryGetGlobalSymbols()) {
symbols = tagSymbols.concat(symbols.filter(s => !!(s.flags & (SymbolFlags.Value | SymbolFlags.Alias))));
}
diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts
index 9f5ceb1f0cb5e..cd6b7b32f1a13 100644
--- a/tests/baselines/reference/api/tsserverlibrary.d.ts
+++ b/tests/baselines/reference/api/tsserverlibrary.d.ts
@@ -1811,7 +1811,7 @@ declare namespace ts {
getAliasedSymbol(symbol: Symbol): Symbol;
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined;
- getJsxIntrinsicTagNames(): Symbol[];
+ getJsxIntrinsicTagNames(location: Node): Symbol[];
isOptionalParameter(node: ParameterDeclaration): boolean;
getAmbientModules(): Symbol[];
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts
index e5fb0b1e1692c..ebfa1f264106f 100644
--- a/tests/baselines/reference/api/typescript.d.ts
+++ b/tests/baselines/reference/api/typescript.d.ts
@@ -1811,7 +1811,7 @@ declare namespace ts {
getAliasedSymbol(symbol: Symbol): Symbol;
getExportsOfModule(moduleSymbol: Symbol): Symbol[];
getAllAttributesTypeFromJsxOpeningLikeElement(elementNode: JsxOpeningLikeElement): Type | undefined;
- getJsxIntrinsicTagNames(): Symbol[];
+ getJsxIntrinsicTagNames(location: Node): Symbol[];
isOptionalParameter(node: ParameterDeclaration): boolean;
getAmbientModules(): Symbol[];
tryGetMemberInModuleExports(memberName: string, moduleSymbol: Symbol): Symbol | undefined;
diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt
new file mode 100644
index 0000000000000..438d492d0208a
--- /dev/null
+++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.errors.txt
@@ -0,0 +1,129 @@
+tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2322: Type 'dom.JSX.Element' is not assignable to type 'predom.JSX.Element'.
+ Property '__predomBrand' is missing in type 'Element'.
+tests/cases/conformance/jsx/inline/index.tsx(21,21): error TS2605: JSX element type 'Element' is not a constructor function for JSX elements.
+ Property 'render' is missing in type 'Element'.
+tests/cases/conformance/jsx/inline/index.tsx(21,28): error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ children?: Element[]; }'.
+ Types of property 'children' are incompatible.
+ Type 'dom.JSX.Element[]' is not assignable to type 'predom.JSX.Element[]'.
+ Type 'dom.JSX.Element' is not assignable to type 'predom.JSX.Element'.
+tests/cases/conformance/jsx/inline/index.tsx(21,40): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
+tests/cases/conformance/jsx/inline/index.tsx(21,40): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
+ Property '__domBrand' is missing in type 'MyClass'.
+tests/cases/conformance/jsx/inline/index.tsx(21,63): error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
+tests/cases/conformance/jsx/inline/index.tsx(24,30): error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ x: number; y: number; children?: Element[]; }'.
+ Types of property 'children' are incompatible.
+ Type 'predom.JSX.Element[]' is not assignable to type 'dom.JSX.Element[]'.
+ Type 'predom.JSX.Element' is not assignable to type 'dom.JSX.Element'.
+ Property '__domBrand' is missing in type 'Element'.
+
+
+==== tests/cases/conformance/jsx/inline/renderer.d.ts (0 errors) ====
+ export namespace dom {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __domBrand: void;
+ props: {
+ children?: Element[];
+ };
+ }
+ interface ElementClass extends Element {
+ render(): Element;
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+ }
+ export function dom(): dom.JSX.Element;
+==== tests/cases/conformance/jsx/inline/renderer2.d.ts (0 errors) ====
+ export namespace predom {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __predomBrand: void;
+ props: {
+ children?: Element[];
+ };
+ }
+ interface ElementClass extends Element {
+ render(): Element;
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+ }
+ export function predom(): predom.JSX.Element;
+==== tests/cases/conformance/jsx/inline/component.tsx (0 errors) ====
+ /** @jsx predom */
+ import { predom } from "./renderer2"
+
+ export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{...this.props.children}
;
+
+ export class MyClass implements predom.JSX.Element {
+ __predomBrand!: void;
+ constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
+ render() {
+ return
+ {this.props.x} + {this.props.y} = {this.props.x + this.props.y}
+ {...this.props.children}
+
;
+ }
+ }
+ export const tree =
+
+ export default
+
+==== tests/cases/conformance/jsx/inline/index.tsx (7 errors) ====
+ /** @jsx dom */
+ import { dom } from "./renderer"
+ import prerendered, {MySFC, MyClass, tree} from "./component";
+ let elem = prerendered;
+ elem = ; // Expect assignability error here
+ ~~~~
+!!! error TS2322: Type 'dom.JSX.Element' is not assignable to type 'predom.JSX.Element'.
+!!! error TS2322: Property '__predomBrand' is missing in type 'Element'.
+
+ const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{props.children}
;
+
+ class DOMClass implements dom.JSX.Element {
+ __domBrand!: void;
+ constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
+ render() {
+ return {this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}
;
+ }
+ }
+
+ // Should work, everything is a DOM element
+ const _tree =
+
+ // Should fail, no dom elements
+ const _brokenTree =
+ ~~~~~~~~~~~~~~~~~~~
+!!! error TS2605: JSX element type 'Element' is not a constructor function for JSX elements.
+!!! error TS2605: Property 'render' is missing in type 'Element'.
+ ~~~~~~~~~~~
+!!! error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ children?: Element[]; }'.
+!!! error TS2322: Types of property 'children' are incompatible.
+!!! error TS2322: Type 'dom.JSX.Element[]' is not assignable to type 'predom.JSX.Element[]'.
+!!! error TS2322: Type 'dom.JSX.Element' is not assignable to type 'predom.JSX.Element'.
+ ~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
+ ~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
+!!! error TS2605: Property '__domBrand' is missing in type 'MyClass'.
+ ~~~~~~~~~~~~~~~~~~~~~~~
+!!! error TS2605: JSX element type 'MyClass' is not a constructor function for JSX elements.
+
+ // Should fail, nondom isn't allowed as children of dom
+ const _brokenTree2 = {tree}{tree}
+ ~~~~~~~~~~~
+!!! error TS2322: Type '{ children: Element[]; x: number; y: number; }' is not assignable to type '{ x: number; y: number; children?: Element[]; }'.
+!!! error TS2322: Types of property 'children' are incompatible.
+!!! error TS2322: Type 'predom.JSX.Element[]' is not assignable to type 'dom.JSX.Element[]'.
+!!! error TS2322: Type 'predom.JSX.Element' is not assignable to type 'dom.JSX.Element'.
+!!! error TS2322: Property '__domBrand' is missing in type 'Element'.
+
\ No newline at end of file
diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js
new file mode 100644
index 0000000000000..87487b4139da4
--- /dev/null
+++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.js
@@ -0,0 +1,164 @@
+//// [tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx] ////
+
+//// [renderer.d.ts]
+export namespace dom {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __domBrand: void;
+ props: {
+ children?: Element[];
+ };
+ }
+ interface ElementClass extends Element {
+ render(): Element;
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+}
+export function dom(): dom.JSX.Element;
+//// [renderer2.d.ts]
+export namespace predom {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __predomBrand: void;
+ props: {
+ children?: Element[];
+ };
+ }
+ interface ElementClass extends Element {
+ render(): Element;
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+}
+export function predom(): predom.JSX.Element;
+//// [component.tsx]
+/** @jsx predom */
+import { predom } from "./renderer2"
+
+export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{...this.props.children}
;
+
+export class MyClass implements predom.JSX.Element {
+ __predomBrand!: void;
+ constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
+ render() {
+ return
+ {this.props.x} + {this.props.y} = {this.props.x + this.props.y}
+ {...this.props.children}
+
;
+ }
+}
+export const tree =
+
+export default
+
+//// [index.tsx]
+/** @jsx dom */
+import { dom } from "./renderer"
+import prerendered, {MySFC, MyClass, tree} from "./component";
+let elem = prerendered;
+elem = ; // Expect assignability error here
+
+const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{props.children}
;
+
+class DOMClass implements dom.JSX.Element {
+ __domBrand!: void;
+ constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
+ render() {
+ return {this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}
;
+ }
+}
+
+// Should work, everything is a DOM element
+const _tree =
+
+// Should fail, no dom elements
+const _brokenTree =
+
+// Should fail, nondom isn't allowed as children of dom
+const _brokenTree2 = {tree}{tree}
+
+
+//// [component.js]
+"use strict";
+var _this = this;
+exports.__esModule = true;
+/** @jsx predom */
+var renderer2_1 = require("./renderer2");
+exports.MySFC = function (props) { return renderer2_1.predom("p", null,
+ props.x,
+ " + ",
+ props.y,
+ " = ",
+ props.x + props.y,
+ _this.props.children); };
+var MyClass = /** @class */ (function () {
+ function MyClass(props) {
+ this.props = props;
+ }
+ MyClass.prototype.render = function () {
+ return renderer2_1.predom("p", null,
+ this.props.x,
+ " + ",
+ this.props.y,
+ " = ",
+ this.props.x + this.props.y,
+ this.props.children);
+ };
+ return MyClass;
+}());
+exports.MyClass = MyClass;
+exports.tree = renderer2_1.predom(exports.MySFC, { x: 1, y: 2 },
+ renderer2_1.predom(MyClass, { x: 3, y: 4 }),
+ renderer2_1.predom(MyClass, { x: 5, y: 6 }));
+exports["default"] = renderer2_1.predom("h", null);
+//// [index.js]
+"use strict";
+exports.__esModule = true;
+/** @jsx dom */
+var renderer_1 = require("./renderer");
+var component_1 = require("./component");
+var elem = component_1["default"];
+elem = renderer_1.dom("h", null); // Expect assignability error here
+var DOMSFC = function (props) { return renderer_1.dom("p", null,
+ props.x,
+ " + ",
+ props.y,
+ " = ",
+ props.x + props.y,
+ props.children); };
+var DOMClass = /** @class */ (function () {
+ function DOMClass(props) {
+ this.props = props;
+ }
+ DOMClass.prototype.render = function () {
+ return renderer_1.dom("p", null,
+ this.props.x,
+ " + ",
+ this.props.y,
+ " = ",
+ this.props.x + this.props.y,
+ this.props.children);
+ };
+ return DOMClass;
+}());
+// Should work, everything is a DOM element
+var _tree = renderer_1.dom(DOMSFC, { x: 1, y: 2 },
+ renderer_1.dom(DOMClass, { x: 3, y: 4 }),
+ renderer_1.dom(DOMClass, { x: 5, y: 6 }));
+// Should fail, no dom elements
+var _brokenTree = renderer_1.dom(component_1.MySFC, { x: 1, y: 2 },
+ renderer_1.dom(component_1.MyClass, { x: 3, y: 4 }),
+ renderer_1.dom(component_1.MyClass, { x: 5, y: 6 }));
+// Should fail, nondom isn't allowed as children of dom
+var _brokenTree2 = renderer_1.dom(DOMSFC, { x: 1, y: 2 },
+ component_1.tree,
+ component_1.tree);
diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.symbols b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.symbols
new file mode 100644
index 0000000000000..c5b4e795cf668
--- /dev/null
+++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.symbols
@@ -0,0 +1,346 @@
+=== tests/cases/conformance/jsx/inline/renderer.d.ts ===
+export namespace dom {
+>dom : Symbol(dom, Decl(renderer.d.ts, 0, 0), Decl(renderer.d.ts, 17, 1))
+
+ namespace JSX {
+>JSX : Symbol(JSX, Decl(renderer.d.ts, 0, 22))
+
+ interface IntrinsicElements {
+>IntrinsicElements : Symbol(IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+
+ [e: string]: {};
+>e : Symbol(e, Decl(renderer.d.ts, 3, 13))
+ }
+ interface Element {
+>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9))
+
+ __domBrand: void;
+>__domBrand : Symbol(Element.__domBrand, Decl(renderer.d.ts, 5, 27))
+
+ props: {
+>props : Symbol(Element.props, Decl(renderer.d.ts, 6, 29))
+
+ children?: Element[];
+>children : Symbol(children, Decl(renderer.d.ts, 7, 20))
+>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9))
+
+ };
+ }
+ interface ElementClass extends Element {
+>ElementClass : Symbol(ElementClass, Decl(renderer.d.ts, 10, 9))
+>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9))
+
+ render(): Element;
+>render : Symbol(ElementClass.render, Decl(renderer.d.ts, 11, 48))
+>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9))
+ }
+ interface ElementAttributesProperty { props: any; }
+>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(renderer.d.ts, 13, 9))
+>props : Symbol(ElementAttributesProperty.props, Decl(renderer.d.ts, 14, 45))
+
+ interface ElementChildrenAttribute { children: any; }
+>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(renderer.d.ts, 14, 59))
+>children : Symbol(ElementChildrenAttribute.children, Decl(renderer.d.ts, 15, 44))
+ }
+}
+export function dom(): dom.JSX.Element;
+>dom : Symbol(dom, Decl(renderer.d.ts, 0, 0), Decl(renderer.d.ts, 17, 1))
+>dom : Symbol(dom, Decl(renderer.d.ts, 0, 0), Decl(renderer.d.ts, 17, 1))
+>JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22))
+>Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9))
+
+=== tests/cases/conformance/jsx/inline/renderer2.d.ts ===
+export namespace predom {
+>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 17, 1))
+
+ namespace JSX {
+>JSX : Symbol(JSX, Decl(renderer2.d.ts, 0, 25))
+
+ interface IntrinsicElements {
+>IntrinsicElements : Symbol(IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+
+ [e: string]: {};
+>e : Symbol(e, Decl(renderer2.d.ts, 3, 13))
+ }
+ interface Element {
+>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9))
+
+ __predomBrand: void;
+>__predomBrand : Symbol(Element.__predomBrand, Decl(renderer2.d.ts, 5, 27))
+
+ props: {
+>props : Symbol(Element.props, Decl(renderer2.d.ts, 6, 32))
+
+ children?: Element[];
+>children : Symbol(children, Decl(renderer2.d.ts, 7, 20))
+>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9))
+
+ };
+ }
+ interface ElementClass extends Element {
+>ElementClass : Symbol(ElementClass, Decl(renderer2.d.ts, 10, 9))
+>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9))
+
+ render(): Element;
+>render : Symbol(ElementClass.render, Decl(renderer2.d.ts, 11, 48))
+>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9))
+ }
+ interface ElementAttributesProperty { props: any; }
+>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(renderer2.d.ts, 13, 9))
+>props : Symbol(ElementAttributesProperty.props, Decl(renderer2.d.ts, 14, 45))
+
+ interface ElementChildrenAttribute { children: any; }
+>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(renderer2.d.ts, 14, 59))
+>children : Symbol(ElementChildrenAttribute.children, Decl(renderer2.d.ts, 15, 44))
+ }
+}
+export function predom(): predom.JSX.Element;
+>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 17, 1))
+>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 17, 1))
+>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25))
+>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9))
+
+=== tests/cases/conformance/jsx/inline/component.tsx ===
+/** @jsx predom */
+import { predom } from "./renderer2"
+>predom : Symbol(predom, Decl(component.tsx, 1, 8))
+
+export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{...this.props.children}
;
+>MySFC : Symbol(MySFC, Decl(component.tsx, 3, 12))
+>props : Symbol(props, Decl(component.tsx, 3, 22))
+>x : Symbol(x, Decl(component.tsx, 3, 30))
+>y : Symbol(y, Decl(component.tsx, 3, 40))
+>children : Symbol(children, Decl(component.tsx, 3, 51))
+>predom : Symbol(predom, Decl(component.tsx, 1, 8))
+>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25))
+>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9))
+>p : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+>props.x : Symbol(x, Decl(component.tsx, 3, 30))
+>props : Symbol(props, Decl(component.tsx, 3, 22))
+>x : Symbol(x, Decl(component.tsx, 3, 30))
+>props.y : Symbol(y, Decl(component.tsx, 3, 40))
+>props : Symbol(props, Decl(component.tsx, 3, 22))
+>y : Symbol(y, Decl(component.tsx, 3, 40))
+>props.x : Symbol(x, Decl(component.tsx, 3, 30))
+>props : Symbol(props, Decl(component.tsx, 3, 22))
+>x : Symbol(x, Decl(component.tsx, 3, 30))
+>props.y : Symbol(y, Decl(component.tsx, 3, 40))
+>props : Symbol(props, Decl(component.tsx, 3, 22))
+>y : Symbol(y, Decl(component.tsx, 3, 40))
+>p : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+
+export class MyClass implements predom.JSX.Element {
+>MyClass : Symbol(MyClass, Decl(component.tsx, 3, 164))
+>predom.JSX.Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9))
+>predom.JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25))
+>predom : Symbol(predom, Decl(component.tsx, 1, 8))
+>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25))
+>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9))
+
+ __predomBrand!: void;
+>__predomBrand : Symbol(MyClass.__predomBrand, Decl(component.tsx, 5, 52))
+
+ constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
+>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>x : Symbol(x, Decl(component.tsx, 7, 31))
+>y : Symbol(y, Decl(component.tsx, 7, 41))
+>children : Symbol(children, Decl(component.tsx, 7, 52))
+>predom : Symbol(predom, Decl(component.tsx, 1, 8))
+>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25))
+>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9))
+
+ render() {
+>render : Symbol(MyClass.render, Decl(component.tsx, 7, 89))
+
+ return
+>p : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+
+ {this.props.x} + {this.props.y} = {this.props.x + this.props.y}
+>this.props.x : Symbol(x, Decl(component.tsx, 7, 31))
+>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>this : Symbol(MyClass, Decl(component.tsx, 3, 164))
+>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>x : Symbol(x, Decl(component.tsx, 7, 31))
+>this.props.y : Symbol(y, Decl(component.tsx, 7, 41))
+>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>this : Symbol(MyClass, Decl(component.tsx, 3, 164))
+>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>y : Symbol(y, Decl(component.tsx, 7, 41))
+>this.props.x : Symbol(x, Decl(component.tsx, 7, 31))
+>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>this : Symbol(MyClass, Decl(component.tsx, 3, 164))
+>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>x : Symbol(x, Decl(component.tsx, 7, 31))
+>this.props.y : Symbol(y, Decl(component.tsx, 7, 41))
+>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>this : Symbol(MyClass, Decl(component.tsx, 3, 164))
+>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>y : Symbol(y, Decl(component.tsx, 7, 41))
+
+ {...this.props.children}
+>this.props.children : Symbol(children, Decl(component.tsx, 7, 52))
+>this.props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>this : Symbol(MyClass, Decl(component.tsx, 3, 164))
+>props : Symbol(MyClass.props, Decl(component.tsx, 7, 16))
+>children : Symbol(children, Decl(component.tsx, 7, 52))
+
+
;
+>p : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+ }
+}
+export const tree =
+>tree : Symbol(tree, Decl(component.tsx, 15, 12))
+>MySFC : Symbol(MySFC, Decl(component.tsx, 3, 12))
+>x : Symbol(x, Decl(component.tsx, 15, 26))
+>y : Symbol(y, Decl(component.tsx, 15, 32))
+>MyClass : Symbol(MyClass, Decl(component.tsx, 3, 164))
+>x : Symbol(x, Decl(component.tsx, 15, 47))
+>y : Symbol(y, Decl(component.tsx, 15, 53))
+>MyClass : Symbol(MyClass, Decl(component.tsx, 3, 164))
+>x : Symbol(x, Decl(component.tsx, 15, 70))
+>y : Symbol(y, Decl(component.tsx, 15, 76))
+>MySFC : Symbol(MySFC, Decl(component.tsx, 3, 12))
+
+export default
+>h : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+>h : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+
+=== tests/cases/conformance/jsx/inline/index.tsx ===
+/** @jsx dom */
+import { dom } from "./renderer"
+>dom : Symbol(dom, Decl(index.tsx, 1, 8))
+
+import prerendered, {MySFC, MyClass, tree} from "./component";
+>prerendered : Symbol(prerendered, Decl(index.tsx, 2, 6))
+>MySFC : Symbol(MySFC, Decl(index.tsx, 2, 21))
+>MyClass : Symbol(MyClass, Decl(index.tsx, 2, 27))
+>tree : Symbol(tree, Decl(index.tsx, 2, 36))
+
+let elem = prerendered;
+>elem : Symbol(elem, Decl(index.tsx, 3, 3))
+>prerendered : Symbol(prerendered, Decl(index.tsx, 2, 6))
+
+elem = ; // Expect assignability error here
+>elem : Symbol(elem, Decl(index.tsx, 3, 3))
+>h : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+>h : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+
+const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{props.children}
;
+>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5))
+>props : Symbol(props, Decl(index.tsx, 6, 16))
+>x : Symbol(x, Decl(index.tsx, 6, 24))
+>y : Symbol(y, Decl(index.tsx, 6, 34))
+>children : Symbol(children, Decl(index.tsx, 6, 45))
+>dom : Symbol(dom, Decl(index.tsx, 1, 8))
+>JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22))
+>Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9))
+>p : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+>props.x : Symbol(x, Decl(index.tsx, 6, 24))
+>props : Symbol(props, Decl(index.tsx, 6, 16))
+>x : Symbol(x, Decl(index.tsx, 6, 24))
+>props.y : Symbol(y, Decl(index.tsx, 6, 34))
+>props : Symbol(props, Decl(index.tsx, 6, 16))
+>y : Symbol(y, Decl(index.tsx, 6, 34))
+>props.x : Symbol(x, Decl(index.tsx, 6, 24))
+>props : Symbol(props, Decl(index.tsx, 6, 16))
+>x : Symbol(x, Decl(index.tsx, 6, 24))
+>props.y : Symbol(y, Decl(index.tsx, 6, 34))
+>props : Symbol(props, Decl(index.tsx, 6, 16))
+>y : Symbol(y, Decl(index.tsx, 6, 34))
+>props.children : Symbol(children, Decl(index.tsx, 6, 45))
+>props : Symbol(props, Decl(index.tsx, 6, 16))
+>children : Symbol(children, Decl(index.tsx, 6, 45))
+>p : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+
+class DOMClass implements dom.JSX.Element {
+>DOMClass : Symbol(DOMClass, Decl(index.tsx, 6, 147))
+>dom.JSX.Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9))
+>dom.JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22))
+>dom : Symbol(dom, Decl(index.tsx, 1, 8))
+>JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22))
+>Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9))
+
+ __domBrand!: void;
+>__domBrand : Symbol(DOMClass.__domBrand, Decl(index.tsx, 8, 43))
+
+ constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
+>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>x : Symbol(x, Decl(index.tsx, 10, 31))
+>y : Symbol(y, Decl(index.tsx, 10, 41))
+>children : Symbol(children, Decl(index.tsx, 10, 52))
+>dom : Symbol(dom, Decl(index.tsx, 1, 8))
+>JSX : Symbol(dom.JSX, Decl(renderer.d.ts, 0, 22))
+>Element : Symbol(dom.JSX.Element, Decl(renderer.d.ts, 4, 9))
+
+ render() {
+>render : Symbol(DOMClass.render, Decl(index.tsx, 10, 86))
+
+ return {this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}
;
+>p : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+>this.props.x : Symbol(x, Decl(index.tsx, 10, 31))
+>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>this : Symbol(DOMClass, Decl(index.tsx, 6, 147))
+>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>x : Symbol(x, Decl(index.tsx, 10, 31))
+>this.props.y : Symbol(y, Decl(index.tsx, 10, 41))
+>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>this : Symbol(DOMClass, Decl(index.tsx, 6, 147))
+>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>y : Symbol(y, Decl(index.tsx, 10, 41))
+>this.props.x : Symbol(x, Decl(index.tsx, 10, 31))
+>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>this : Symbol(DOMClass, Decl(index.tsx, 6, 147))
+>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>x : Symbol(x, Decl(index.tsx, 10, 31))
+>this.props.y : Symbol(y, Decl(index.tsx, 10, 41))
+>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>this : Symbol(DOMClass, Decl(index.tsx, 6, 147))
+>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>y : Symbol(y, Decl(index.tsx, 10, 41))
+>this.props.children : Symbol(children, Decl(index.tsx, 10, 52))
+>this.props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>this : Symbol(DOMClass, Decl(index.tsx, 6, 147))
+>props : Symbol(DOMClass.props, Decl(index.tsx, 10, 16))
+>children : Symbol(children, Decl(index.tsx, 10, 52))
+>p : Symbol(dom.JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+ }
+}
+
+// Should work, everything is a DOM element
+const _tree =
+>_tree : Symbol(_tree, Decl(index.tsx, 17, 5))
+>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5))
+>x : Symbol(x, Decl(index.tsx, 17, 21))
+>y : Symbol(y, Decl(index.tsx, 17, 27))
+>DOMClass : Symbol(DOMClass, Decl(index.tsx, 6, 147))
+>x : Symbol(x, Decl(index.tsx, 17, 43))
+>y : Symbol(y, Decl(index.tsx, 17, 49))
+>DOMClass : Symbol(DOMClass, Decl(index.tsx, 6, 147))
+>x : Symbol(x, Decl(index.tsx, 17, 67))
+>y : Symbol(y, Decl(index.tsx, 17, 73))
+>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5))
+
+// Should fail, no dom elements
+const _brokenTree =
+>_brokenTree : Symbol(_brokenTree, Decl(index.tsx, 20, 5))
+>MySFC : Symbol(MySFC, Decl(index.tsx, 2, 21))
+>x : Symbol(x, Decl(index.tsx, 20, 26))
+>y : Symbol(y, Decl(index.tsx, 20, 32))
+>MyClass : Symbol(MyClass, Decl(index.tsx, 2, 27))
+>x : Symbol(x, Decl(index.tsx, 20, 47))
+>y : Symbol(y, Decl(index.tsx, 20, 53))
+>MyClass : Symbol(MyClass, Decl(index.tsx, 2, 27))
+>x : Symbol(x, Decl(index.tsx, 20, 70))
+>y : Symbol(y, Decl(index.tsx, 20, 76))
+>MySFC : Symbol(MySFC, Decl(index.tsx, 2, 21))
+
+// Should fail, nondom isn't allowed as children of dom
+const _brokenTree2 = {tree}{tree}
+>_brokenTree2 : Symbol(_brokenTree2, Decl(index.tsx, 23, 5))
+>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5))
+>x : Symbol(x, Decl(index.tsx, 23, 28))
+>y : Symbol(y, Decl(index.tsx, 23, 34))
+>tree : Symbol(tree, Decl(index.tsx, 2, 36))
+>tree : Symbol(tree, Decl(index.tsx, 2, 36))
+>DOMSFC : Symbol(DOMSFC, Decl(index.tsx, 6, 5))
+
diff --git a/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.types b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.types
new file mode 100644
index 0000000000000..d33da0d6494ce
--- /dev/null
+++ b/tests/baselines/reference/inlineJsxFactoryDeclarationsLocalTypes.types
@@ -0,0 +1,394 @@
+=== tests/cases/conformance/jsx/inline/renderer.d.ts ===
+export namespace dom {
+>dom : () => JSX.Element
+
+ namespace JSX {
+>JSX : any
+
+ interface IntrinsicElements {
+>IntrinsicElements : IntrinsicElements
+
+ [e: string]: {};
+>e : string
+ }
+ interface Element {
+>Element : Element
+
+ __domBrand: void;
+>__domBrand : void
+
+ props: {
+>props : { children?: Element[]; }
+
+ children?: Element[];
+>children : Element[]
+>Element : Element
+
+ };
+ }
+ interface ElementClass extends Element {
+>ElementClass : ElementClass
+>Element : Element
+
+ render(): Element;
+>render : () => Element
+>Element : Element
+ }
+ interface ElementAttributesProperty { props: any; }
+>ElementAttributesProperty : ElementAttributesProperty
+>props : any
+
+ interface ElementChildrenAttribute { children: any; }
+>ElementChildrenAttribute : ElementChildrenAttribute
+>children : any
+ }
+}
+export function dom(): dom.JSX.Element;
+>dom : () => dom.JSX.Element
+>dom : any
+>JSX : any
+>Element : dom.JSX.Element
+
+=== tests/cases/conformance/jsx/inline/renderer2.d.ts ===
+export namespace predom {
+>predom : () => JSX.Element
+
+ namespace JSX {
+>JSX : any
+
+ interface IntrinsicElements {
+>IntrinsicElements : IntrinsicElements
+
+ [e: string]: {};
+>e : string
+ }
+ interface Element {
+>Element : Element
+
+ __predomBrand: void;
+>__predomBrand : void
+
+ props: {
+>props : { children?: Element[]; }
+
+ children?: Element[];
+>children : Element[]
+>Element : Element
+
+ };
+ }
+ interface ElementClass extends Element {
+>ElementClass : ElementClass
+>Element : Element
+
+ render(): Element;
+>render : () => Element
+>Element : Element
+ }
+ interface ElementAttributesProperty { props: any; }
+>ElementAttributesProperty : ElementAttributesProperty
+>props : any
+
+ interface ElementChildrenAttribute { children: any; }
+>ElementChildrenAttribute : ElementChildrenAttribute
+>children : any
+ }
+}
+export function predom(): predom.JSX.Element;
+>predom : () => predom.JSX.Element
+>predom : any
+>JSX : any
+>Element : predom.JSX.Element
+
+=== tests/cases/conformance/jsx/inline/component.tsx ===
+/** @jsx predom */
+import { predom } from "./renderer2"
+>predom : () => predom.JSX.Element
+
+export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{...this.props.children}
;
+>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element
+>(props: {x: number, y: number, children?: predom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{...this.props.children}
: (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>x : number
+>y : number
+>children : predom.JSX.Element[]
+>predom : any
+>JSX : any
+>Element : predom.JSX.Element
+>{props.x} + {props.y} = {props.x + props.y}{...this.props.children}
: predom.JSX.Element
+>p : any
+>props.x : number
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>x : number
+>props.y : number
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>y : number
+>props.x + props.y : number
+>props.x : number
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>x : number
+>props.y : number
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>y : number
+>this.props.children : any
+>this.props : any
+>this : any
+>props : any
+>children : any
+>p : any
+
+export class MyClass implements predom.JSX.Element {
+>MyClass : MyClass
+>predom.JSX.Element : any
+>predom.JSX : any
+>predom : () => predom.JSX.Element
+>JSX : any
+>Element : predom.JSX.Element
+
+ __predomBrand!: void;
+>__predomBrand : void
+
+ constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>x : number
+>y : number
+>children : predom.JSX.Element[]
+>predom : any
+>JSX : any
+>Element : predom.JSX.Element
+
+ render() {
+>render : () => predom.JSX.Element
+
+ return
+>
{this.props.x} + {this.props.y} = {this.props.x + this.props.y} {...this.props.children}
: predom.JSX.Element
+>p : any
+
+ {this.props.x} + {this.props.y} = {this.props.x + this.props.y}
+>this.props.x : number
+>this.props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>x : number
+>this.props.y : number
+>this.props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>y : number
+>this.props.x + this.props.y : number
+>this.props.x : number
+>this.props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>x : number
+>this.props.y : number
+>this.props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>y : number
+
+ {...this.props.children}
+>this.props.children : predom.JSX.Element[]
+>this.props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: predom.JSX.Element[]; }
+>children : predom.JSX.Element[]
+
+
;
+>p : any
+ }
+}
+export const tree =
+>tree : predom.JSX.Element
+> : predom.JSX.Element
+>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element
+>x : number
+>1 : 1
+>y : number
+>2 : 2
+> : predom.JSX.Element
+>MyClass : typeof MyClass
+>x : number
+>3 : 3
+>y : number
+>4 : 4
+> : predom.JSX.Element
+>MyClass : typeof MyClass
+>x : number
+>5 : 5
+>y : number
+>6 : 6
+>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element
+
+export default
+> : predom.JSX.Element
+>h : any
+>h : any
+
+=== tests/cases/conformance/jsx/inline/index.tsx ===
+/** @jsx dom */
+import { dom } from "./renderer"
+>dom : () => dom.JSX.Element
+
+import prerendered, {MySFC, MyClass, tree} from "./component";
+>prerendered : predom.JSX.Element
+>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element
+>MyClass : typeof MyClass
+>tree : predom.JSX.Element
+
+let elem = prerendered;
+>elem : predom.JSX.Element
+>prerendered : predom.JSX.Element
+
+elem = ; // Expect assignability error here
+>elem = : dom.JSX.Element
+>elem : predom.JSX.Element
+> : dom.JSX.Element
+>h : any
+>h : any
+
+const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{props.children}
;
+>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element
+>(props: {x: number, y: number, children?: dom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{props.children}
: (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>x : number
+>y : number
+>children : dom.JSX.Element[]
+>dom : any
+>JSX : any
+>Element : dom.JSX.Element
+>{props.x} + {props.y} = {props.x + props.y}{props.children}
: dom.JSX.Element
+>p : any
+>props.x : number
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>x : number
+>props.y : number
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>y : number
+>props.x + props.y : number
+>props.x : number
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>x : number
+>props.y : number
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>y : number
+>props.children : dom.JSX.Element[]
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>children : dom.JSX.Element[]
+>p : any
+
+class DOMClass implements dom.JSX.Element {
+>DOMClass : DOMClass
+>dom.JSX.Element : any
+>dom.JSX : any
+>dom : () => dom.JSX.Element
+>JSX : any
+>Element : dom.JSX.Element
+
+ __domBrand!: void;
+>__domBrand : void
+
+ constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>x : number
+>y : number
+>children : dom.JSX.Element[]
+>dom : any
+>JSX : any
+>Element : dom.JSX.Element
+
+ render() {
+>render : () => dom.JSX.Element
+
+ return {this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}
;
+>{this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}
: dom.JSX.Element
+>p : any
+>this.props.x : number
+>this.props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>x : number
+>this.props.y : number
+>this.props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>y : number
+>this.props.x + this.props.y : number
+>this.props.x : number
+>this.props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>x : number
+>this.props.y : number
+>this.props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>y : number
+>this.props.children : dom.JSX.Element[]
+>this.props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>this : this
+>props : { x: number; y: number; children?: dom.JSX.Element[]; }
+>children : dom.JSX.Element[]
+>p : any
+ }
+}
+
+// Should work, everything is a DOM element
+const _tree =
+>_tree : dom.JSX.Element
+> : dom.JSX.Element
+>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element
+>x : number
+>1 : 1
+>y : number
+>2 : 2
+> : dom.JSX.Element
+>DOMClass : typeof DOMClass
+>x : number
+>3 : 3
+>y : number
+>4 : 4
+> : dom.JSX.Element
+>DOMClass : typeof DOMClass
+>x : number
+>5 : 5
+>y : number
+>6 : 6
+>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element
+
+// Should fail, no dom elements
+const _brokenTree =
+>_brokenTree : dom.JSX.Element
+> : dom.JSX.Element
+>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element
+>x : number
+>1 : 1
+>y : number
+>2 : 2
+> : dom.JSX.Element
+>MyClass : typeof MyClass
+>x : number
+>3 : 3
+>y : number
+>4 : 4
+> : dom.JSX.Element
+>MyClass : typeof MyClass
+>x : number
+>5 : 5
+>y : number
+>6 : 6
+>MySFC : (props: { x: number; y: number; children?: predom.JSX.Element[]; }) => predom.JSX.Element
+
+// Should fail, nondom isn't allowed as children of dom
+const _brokenTree2 = {tree}{tree}
+>_brokenTree2 : dom.JSX.Element
+>{tree}{tree} : dom.JSX.Element
+>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element
+>x : number
+>1 : 1
+>y : number
+>2 : 2
+>tree : predom.JSX.Element
+>tree : predom.JSX.Element
+>DOMSFC : (props: { x: number; y: number; children?: dom.JSX.Element[]; }) => dom.JSX.Element
+
diff --git a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt
new file mode 100644
index 0000000000000..9d4e4e0a026f5
--- /dev/null
+++ b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.errors.txt
@@ -0,0 +1,51 @@
+tests/cases/conformance/jsx/inline/index.tsx(5,1): error TS2322: Type 'JSX.Element' is not assignable to type 'predom.JSX.Element'.
+ Property '__predomBrand' is missing in type 'Element'.
+
+
+==== tests/cases/conformance/jsx/inline/renderer.d.ts (0 errors) ====
+ declare global {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __domBrand: void;
+ children: Element[];
+ props: {};
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+ }
+ export function dom(): JSX.Element;
+==== tests/cases/conformance/jsx/inline/renderer2.d.ts (0 errors) ====
+ export namespace predom {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __predomBrand: void;
+ children: Element[];
+ props: {};
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+ }
+ export function predom(): predom.JSX.Element;
+==== tests/cases/conformance/jsx/inline/component.tsx (0 errors) ====
+ /** @jsx predom */
+ import { predom } from "./renderer2"
+ export default
+
+==== tests/cases/conformance/jsx/inline/index.tsx (1 errors) ====
+ /** @jsx dom */
+ import { dom } from "./renderer"
+ import prerendered from "./component";
+ let elem = prerendered;
+ elem = ; // Expect assignability error here
+ ~~~~
+!!! error TS2322: Type 'JSX.Element' is not assignable to type 'predom.JSX.Element'.
+!!! error TS2322: Property '__predomBrand' is missing in type 'Element'.
+
\ No newline at end of file
diff --git a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.js b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.js
new file mode 100644
index 0000000000000..4f5123ed67ddf
--- /dev/null
+++ b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.js
@@ -0,0 +1,61 @@
+//// [tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx] ////
+
+//// [renderer.d.ts]
+declare global {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __domBrand: void;
+ children: Element[];
+ props: {};
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+}
+export function dom(): JSX.Element;
+//// [renderer2.d.ts]
+export namespace predom {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __predomBrand: void;
+ children: Element[];
+ props: {};
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+}
+export function predom(): predom.JSX.Element;
+//// [component.tsx]
+/** @jsx predom */
+import { predom } from "./renderer2"
+export default
+
+//// [index.tsx]
+/** @jsx dom */
+import { dom } from "./renderer"
+import prerendered from "./component";
+let elem = prerendered;
+elem = ; // Expect assignability error here
+
+
+//// [component.js]
+"use strict";
+exports.__esModule = true;
+/** @jsx predom */
+var renderer2_1 = require("./renderer2");
+exports["default"] = renderer2_1.predom("h", null);
+//// [index.js]
+"use strict";
+exports.__esModule = true;
+/** @jsx dom */
+var renderer_1 = require("./renderer");
+var component_1 = require("./component");
+var elem = component_1["default"];
+elem = renderer_1.dom("h", null); // Expect assignability error here
diff --git a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.symbols b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.symbols
new file mode 100644
index 0000000000000..c496201587190
--- /dev/null
+++ b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.symbols
@@ -0,0 +1,107 @@
+=== tests/cases/conformance/jsx/inline/renderer.d.ts ===
+declare global {
+>global : Symbol(global, Decl(renderer.d.ts, 0, 0))
+
+ namespace JSX {
+>JSX : Symbol(JSX, Decl(renderer.d.ts, 0, 16))
+
+ interface IntrinsicElements {
+>IntrinsicElements : Symbol(IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+
+ [e: string]: {};
+>e : Symbol(e, Decl(renderer.d.ts, 3, 13))
+ }
+ interface Element {
+>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9))
+
+ __domBrand: void;
+>__domBrand : Symbol(Element.__domBrand, Decl(renderer.d.ts, 5, 27))
+
+ children: Element[];
+>children : Symbol(Element.children, Decl(renderer.d.ts, 6, 29))
+>Element : Symbol(Element, Decl(renderer.d.ts, 4, 9))
+
+ props: {};
+>props : Symbol(Element.props, Decl(renderer.d.ts, 7, 32))
+ }
+ interface ElementAttributesProperty { props: any; }
+>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(renderer.d.ts, 9, 9))
+>props : Symbol(ElementAttributesProperty.props, Decl(renderer.d.ts, 10, 45))
+
+ interface ElementChildrenAttribute { children: any; }
+>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(renderer.d.ts, 10, 59))
+>children : Symbol(ElementChildrenAttribute.children, Decl(renderer.d.ts, 11, 44))
+ }
+}
+export function dom(): JSX.Element;
+>dom : Symbol(dom, Decl(renderer.d.ts, 13, 1))
+>JSX : Symbol(JSX, Decl(renderer.d.ts, 0, 16))
+>Element : Symbol(JSX.Element, Decl(renderer.d.ts, 4, 9))
+
+=== tests/cases/conformance/jsx/inline/renderer2.d.ts ===
+export namespace predom {
+>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 13, 1))
+
+ namespace JSX {
+>JSX : Symbol(JSX, Decl(renderer2.d.ts, 0, 25))
+
+ interface IntrinsicElements {
+>IntrinsicElements : Symbol(IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+
+ [e: string]: {};
+>e : Symbol(e, Decl(renderer2.d.ts, 3, 13))
+ }
+ interface Element {
+>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9))
+
+ __predomBrand: void;
+>__predomBrand : Symbol(Element.__predomBrand, Decl(renderer2.d.ts, 5, 27))
+
+ children: Element[];
+>children : Symbol(Element.children, Decl(renderer2.d.ts, 6, 32))
+>Element : Symbol(Element, Decl(renderer2.d.ts, 4, 9))
+
+ props: {};
+>props : Symbol(Element.props, Decl(renderer2.d.ts, 7, 32))
+ }
+ interface ElementAttributesProperty { props: any; }
+>ElementAttributesProperty : Symbol(ElementAttributesProperty, Decl(renderer2.d.ts, 9, 9))
+>props : Symbol(ElementAttributesProperty.props, Decl(renderer2.d.ts, 10, 45))
+
+ interface ElementChildrenAttribute { children: any; }
+>ElementChildrenAttribute : Symbol(ElementChildrenAttribute, Decl(renderer2.d.ts, 10, 59))
+>children : Symbol(ElementChildrenAttribute.children, Decl(renderer2.d.ts, 11, 44))
+ }
+}
+export function predom(): predom.JSX.Element;
+>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 13, 1))
+>predom : Symbol(predom, Decl(renderer2.d.ts, 0, 0), Decl(renderer2.d.ts, 13, 1))
+>JSX : Symbol(predom.JSX, Decl(renderer2.d.ts, 0, 25))
+>Element : Symbol(predom.JSX.Element, Decl(renderer2.d.ts, 4, 9))
+
+=== tests/cases/conformance/jsx/inline/component.tsx ===
+/** @jsx predom */
+import { predom } from "./renderer2"
+>predom : Symbol(predom, Decl(component.tsx, 1, 8))
+
+export default
+>h : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+>h : Symbol(predom.JSX.IntrinsicElements, Decl(renderer2.d.ts, 1, 19))
+
+=== tests/cases/conformance/jsx/inline/index.tsx ===
+/** @jsx dom */
+import { dom } from "./renderer"
+>dom : Symbol(dom, Decl(index.tsx, 1, 8))
+
+import prerendered from "./component";
+>prerendered : Symbol(prerendered, Decl(index.tsx, 2, 6))
+
+let elem = prerendered;
+>elem : Symbol(elem, Decl(index.tsx, 3, 3))
+>prerendered : Symbol(prerendered, Decl(index.tsx, 2, 6))
+
+elem = ; // Expect assignability error here
+>elem : Symbol(elem, Decl(index.tsx, 3, 3))
+>h : Symbol(JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+>h : Symbol(JSX.IntrinsicElements, Decl(renderer.d.ts, 1, 19))
+
diff --git a/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.types b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.types
new file mode 100644
index 0000000000000..369341f0f7a13
--- /dev/null
+++ b/tests/baselines/reference/inlineJsxFactoryLocalTypeGlobalFallback.types
@@ -0,0 +1,110 @@
+=== tests/cases/conformance/jsx/inline/renderer.d.ts ===
+declare global {
+>global : any
+
+ namespace JSX {
+>JSX : any
+
+ interface IntrinsicElements {
+>IntrinsicElements : IntrinsicElements
+
+ [e: string]: {};
+>e : string
+ }
+ interface Element {
+>Element : Element
+
+ __domBrand: void;
+>__domBrand : void
+
+ children: Element[];
+>children : Element[]
+>Element : Element
+
+ props: {};
+>props : {}
+ }
+ interface ElementAttributesProperty { props: any; }
+>ElementAttributesProperty : ElementAttributesProperty
+>props : any
+
+ interface ElementChildrenAttribute { children: any; }
+>ElementChildrenAttribute : ElementChildrenAttribute
+>children : any
+ }
+}
+export function dom(): JSX.Element;
+>dom : () => JSX.Element
+>JSX : any
+>Element : JSX.Element
+
+=== tests/cases/conformance/jsx/inline/renderer2.d.ts ===
+export namespace predom {
+>predom : () => JSX.Element
+
+ namespace JSX {
+>JSX : any
+
+ interface IntrinsicElements {
+>IntrinsicElements : IntrinsicElements
+
+ [e: string]: {};
+>e : string
+ }
+ interface Element {
+>Element : Element
+
+ __predomBrand: void;
+>__predomBrand : void
+
+ children: Element[];
+>children : Element[]
+>Element : Element
+
+ props: {};
+>props : {}
+ }
+ interface ElementAttributesProperty { props: any; }
+>ElementAttributesProperty : ElementAttributesProperty
+>props : any
+
+ interface ElementChildrenAttribute { children: any; }
+>ElementChildrenAttribute : ElementChildrenAttribute
+>children : any
+ }
+}
+export function predom(): predom.JSX.Element;
+>predom : () => predom.JSX.Element
+>predom : any
+>JSX : any
+>Element : predom.JSX.Element
+
+=== tests/cases/conformance/jsx/inline/component.tsx ===
+/** @jsx predom */
+import { predom } from "./renderer2"
+>predom : () => predom.JSX.Element
+
+export default
+> : predom.JSX.Element
+>h : any
+>h : any
+
+=== tests/cases/conformance/jsx/inline/index.tsx ===
+/** @jsx dom */
+import { dom } from "./renderer"
+>dom : () => JSX.Element
+
+import prerendered from "./component";
+>prerendered : predom.JSX.Element
+
+let elem = prerendered;
+>elem : predom.JSX.Element
+>prerendered : predom.JSX.Element
+
+elem = ; // Expect assignability error here
+>elem = : JSX.Element
+>elem : predom.JSX.Element
+> : JSX.Element
+>h : any
+>h : any
+
diff --git a/tests/baselines/reference/tsxElementResolution16.errors.txt b/tests/baselines/reference/tsxElementResolution16.errors.txt
index b68c442c36d66..07b2ec54b44a0 100644
--- a/tests/baselines/reference/tsxElementResolution16.errors.txt
+++ b/tests/baselines/reference/tsxElementResolution16.errors.txt
@@ -1,8 +1,7 @@
-tests/cases/conformance/jsx/file.tsx(8,1): error TS2602: JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist.
tests/cases/conformance/jsx/file.tsx(8,1): error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
-==== tests/cases/conformance/jsx/file.tsx (2 errors) ====
+==== tests/cases/conformance/jsx/file.tsx (1 errors) ====
declare module JSX {
}
@@ -12,7 +11,5 @@ tests/cases/conformance/jsx/file.tsx(8,1): error TS7026: JSX element implicitly
var obj1: Obj1;
; // Error (JSX.Element is implicit any)
~~~~~~~~~~~~~~~
-!!! error TS2602: JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist.
- ~~~~~~~~~~~~~~~
!!! error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.
\ No newline at end of file
diff --git a/tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx b/tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx
new file mode 100644
index 0000000000000..009abe2e852c8
--- /dev/null
+++ b/tests/cases/conformance/jsx/inline/inlineJsxFactoryDeclarationsLocalTypes.tsx
@@ -0,0 +1,86 @@
+// @jsx: react
+// @filename: renderer.d.ts
+export namespace dom {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __domBrand: void;
+ props: {
+ children?: Element[];
+ };
+ }
+ interface ElementClass extends Element {
+ render(): Element;
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+}
+export function dom(): dom.JSX.Element;
+// @filename: renderer2.d.ts
+export namespace predom {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __predomBrand: void;
+ props: {
+ children?: Element[];
+ };
+ }
+ interface ElementClass extends Element {
+ render(): Element;
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+}
+export function predom(): predom.JSX.Element;
+// @filename: component.tsx
+/** @jsx predom */
+import { predom } from "./renderer2"
+
+export const MySFC = (props: {x: number, y: number, children?: predom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{...this.props.children}
;
+
+export class MyClass implements predom.JSX.Element {
+ __predomBrand!: void;
+ constructor(public props: {x: number, y: number, children?: predom.JSX.Element[]}) {}
+ render() {
+ return
+ {this.props.x} + {this.props.y} = {this.props.x + this.props.y}
+ {...this.props.children}
+
;
+ }
+}
+export const tree =
+
+export default
+
+// @filename: index.tsx
+/** @jsx dom */
+import { dom } from "./renderer"
+import prerendered, {MySFC, MyClass, tree} from "./component";
+let elem = prerendered;
+elem = ; // Expect assignability error here
+
+const DOMSFC = (props: {x: number, y: number, children?: dom.JSX.Element[]}) => {props.x} + {props.y} = {props.x + props.y}{props.children}
;
+
+class DOMClass implements dom.JSX.Element {
+ __domBrand!: void;
+ constructor(public props: {x: number, y: number, children?: dom.JSX.Element[]}) {}
+ render() {
+ return {this.props.x} + {this.props.y} = {this.props.x + this.props.y}{...this.props.children}
;
+ }
+}
+
+// Should work, everything is a DOM element
+const _tree =
+
+// Should fail, no dom elements
+const _brokenTree =
+
+// Should fail, nondom isn't allowed as children of dom
+const _brokenTree2 = {tree}{tree}
diff --git a/tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx b/tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx
new file mode 100644
index 0000000000000..3f4340f518b4b
--- /dev/null
+++ b/tests/cases/conformance/jsx/inline/inlineJsxFactoryLocalTypeGlobalFallback.tsx
@@ -0,0 +1,44 @@
+// @jsx: react
+// @filename: renderer.d.ts
+declare global {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __domBrand: void;
+ children: Element[];
+ props: {};
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+}
+export function dom(): JSX.Element;
+// @filename: renderer2.d.ts
+export namespace predom {
+ namespace JSX {
+ interface IntrinsicElements {
+ [e: string]: {};
+ }
+ interface Element {
+ __predomBrand: void;
+ children: Element[];
+ props: {};
+ }
+ interface ElementAttributesProperty { props: any; }
+ interface ElementChildrenAttribute { children: any; }
+ }
+}
+export function predom(): predom.JSX.Element;
+// @filename: component.tsx
+/** @jsx predom */
+import { predom } from "./renderer2"
+export default
+
+// @filename: index.tsx
+/** @jsx dom */
+import { dom } from "./renderer"
+import prerendered from "./component";
+let elem = prerendered;
+elem = ; // Expect assignability error here