@@ -423,17 +423,20 @@ namespace ts {
423423
424424 let _jsxNamespace: string;
425425 let _jsxFactoryEntity: EntityName;
426- let _jsxElementAttribPropInterfaceSymbol: Symbol; // JSX.ElementAttributesProperty [symbol]
427426 let _jsxElementPropertiesName: string;
427+ let _hasComputedJsxElementPropertiesName = false;
428428 let _jsxElementChildrenPropertyName: string;
429+ let _hasComputedJsxElementChildrenPropertyName = false;
429430
430431 /** Things we lazy load from the JSX namespace */
431432 const jsxTypes = createMap<Type>();
433+
432434 const JsxNames = {
433435 JSX: "JSX",
434436 IntrinsicElements: "IntrinsicElements",
435437 ElementClass: "ElementClass",
436438 ElementAttributesPropertyNameContainer: "ElementAttributesProperty",
439+ ElementChildrenAttributeNameContainer: "ElementChildrenAttribute",
437440 Element: "Element",
438441 IntrinsicAttributes: "IntrinsicAttributes",
439442 IntrinsicClassAttributes: "IntrinsicClassAttributes"
@@ -12696,7 +12699,7 @@ namespace ts {
1269612699 else if (node.parent.kind === SyntaxKind.JsxElement) {
1269712700 // JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
1269812701 const jsxChildrenPropertyName = getJsxElementChildrenPropertyname();
12699- return jsxChildrenPropertyName ? getTypeOfPropertyOfType(attributesType, jsxChildrenPropertyName) : anyType;
12702+ return jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfType(attributesType, jsxChildrenPropertyName) : anyType;
1270012703 }
1270112704 else {
1270212705 // JSX expression is in JSX spread attribute
@@ -13361,7 +13364,7 @@ namespace ts {
1336113364 // Error if there is a attribute named "children" and children element.
1336213365 // This is because children element will overwrite the value from attributes
1336313366 const jsxChildrenPropertyName = getJsxElementChildrenPropertyname();
13364- if (jsxChildrenPropertyName) {
13367+ if (jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ) {
1336513368 if (attributesTable.has(jsxChildrenPropertyName)) {
1336613369 error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, jsxChildrenPropertyName);
1336713370 }
@@ -13474,14 +13477,34 @@ namespace ts {
1347413477 return getUnionType(map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
1347513478 }
1347613479
13477- function getPropertiesFromJsxElementAttributesProperty() {
13478- if (!_jsxElementAttribPropInterfaceSymbol) {
13479- // JSX
13480- const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined);
13481- // JSX.ElementAttributesProperty [symbol]
13482- _jsxElementAttribPropInterfaceSymbol = jsxNamespace && getSymbol(jsxNamespace.exports, JsxNames.ElementAttributesPropertyNameContainer, SymbolFlags.Type);
13480+ /**
13481+ *
13482+ */
13483+ function getNameFromJsxElementAttributesContainer(nameOfAttribPropContainer: string): string {
13484+ // JSX
13485+ const jsxNamespace = getGlobalSymbol(JsxNames.JSX, SymbolFlags.Namespace, /*diagnosticMessage*/ undefined);
13486+ // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [symbol]
13487+ const jsxElementAttribPropInterfaceSym = jsxNamespace && getSymbol(jsxNamespace.exports, nameOfAttribPropContainer, SymbolFlags.Type);
13488+ // JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute [type]
13489+ const jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym);
13490+ // The properties of JSX.ElementAttributesProperty | JSX.ElementChildrenAttribute
13491+ const propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType);
13492+ if (propertiesOfJsxElementAttribPropInterface) {
13493+ // Element Attributes has zero properties, so the element attributes type will be the class instance type
13494+ if (propertiesOfJsxElementAttribPropInterface.length === 0) {
13495+ return "";
13496+ }
13497+ // Element Attributes has one property, so the element attributes type will be the type of the corresponding
13498+ // property of the class instance type
13499+ else if (propertiesOfJsxElementAttribPropInterface.length === 1) {
13500+ return propertiesOfJsxElementAttribPropInterface[0].name;
13501+ }
13502+ else if (propertiesOfJsxElementAttribPropInterface.length > 1) {
13503+ // More than one property on ElementAttributesProperty is an error
13504+ error(jsxElementAttribPropInterfaceSym.declarations[0], Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, nameOfAttribPropContainer);
13505+ }
1348313506 }
13484- return _jsxElementAttribPropInterfaceSymbol ;
13507+ return undefined ;
1348513508 }
1348613509
1348713510 /// e.g. "props" for React.d.ts,
@@ -13490,66 +13513,18 @@ namespace ts {
1349013513 /// or '' if it has 0 properties (which means every
1349113514 /// non-intrinsic elements' attributes type is the element instance type)
1349213515 function getJsxElementPropertiesName() {
13493- if (!_jsxElementPropertiesName) {
13494- const jsxElementAttribPropInterfaceSym = getPropertiesFromJsxElementAttributesProperty();
13495- // JSX.ElementAttributesProperty [type]
13496- const jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym);
13497- // The properties of JSX.ElementAttributesProperty
13498- const propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType);
13499-
13500- // if there is a property in JSX.ElementAttributesProperty
13501- // i.e.
13502- // interface ElementAttributesProperty {
13503- // props: {
13504- // children?: any;
13505- // };
13506- // }
13507- if (propertiesOfJsxElementAttribPropInterface) {
13508- // Element Attributes has zero properties, so the element attributes type will be the class instance type
13509- if (propertiesOfJsxElementAttribPropInterface.length === 0) {
13510- _jsxElementPropertiesName = "";
13511- }
13512- // Element Attributes has one property, so the element attributes type will be the type of the corresponding
13513- // property of the class instance type
13514- else if (propertiesOfJsxElementAttribPropInterface.length === 1) {
13515- _jsxElementPropertiesName = propertiesOfJsxElementAttribPropInterface[0].name;
13516- }
13517- // More than one property on ElementAttributesProperty is an error
13518- else {
13519- error(jsxElementAttribPropInterfaceSym.declarations[0], Diagnostics.The_global_type_JSX_0_may_not_have_more_than_one_property, JsxNames.ElementAttributesPropertyNameContainer);
13520- _jsxElementPropertiesName = undefined;
13521- }
13522- }
13523- else {
13524- // No interface exists, so the element attributes type will be an implicit any
13525- _jsxElementPropertiesName = undefined;
13526- }
13516+ if (!_hasComputedJsxElementPropertiesName) {
13517+ _hasComputedJsxElementPropertiesName = true;
13518+ _jsxElementPropertiesName = getNameFromJsxElementAttributesContainer(JsxNames.ElementAttributesPropertyNameContainer);
1352713519 }
1352813520
1352913521 return _jsxElementPropertiesName;
1353013522 }
1353113523
1353213524 function getJsxElementChildrenPropertyname(): string {
13533- if (!_jsxElementChildrenPropertyName) {
13534- const jsxElementAttribPropInterfaceSym = getPropertiesFromJsxElementAttributesProperty();
13535- // JSX.ElementAttributesProperty [type]
13536- const jsxElementAttribPropInterfaceType = jsxElementAttribPropInterfaceSym && getDeclaredTypeOfSymbol(jsxElementAttribPropInterfaceSym);
13537- // The properties of JSX.ElementAttributesProperty
13538- const propertiesOfJsxElementAttribPropInterface = jsxElementAttribPropInterfaceType && getPropertiesOfType(jsxElementAttribPropInterfaceType);
13539- // if there is a property in JSX.ElementAttributesProperty
13540- // i.e.
13541- // interface ElementAttributesProperty {
13542- // props: {
13543- // children?: any;
13544- // };
13545- // }
13546- if (propertiesOfJsxElementAttribPropInterface && propertiesOfJsxElementAttribPropInterface.length === 1) {
13547- const propsType = getTypeOfSymbol(propertiesOfJsxElementAttribPropInterface[0]);
13548- const propertiesOfProps = propsType && getPropertiesOfType(propsType);
13549- if (propertiesOfProps && propertiesOfProps.length === 1) {
13550- _jsxElementChildrenPropertyName = propertiesOfProps[0].name;
13551- }
13552- }
13525+ if (!_hasComputedJsxElementChildrenPropertyName) {
13526+ _hasComputedJsxElementChildrenPropertyName = true;
13527+ _jsxElementChildrenPropertyName = getNameFromJsxElementAttributesContainer(JsxNames.ElementChildrenAttributeNameContainer);
1355313528 }
1355413529
1355513530 return _jsxElementChildrenPropertyName;
0 commit comments