@@ -423,17 +423,20 @@ namespace ts {
423
423
424
424
let _jsxNamespace: string;
425
425
let _jsxFactoryEntity: EntityName;
426
- let _jsxElementAttribPropInterfaceSymbol: Symbol; // JSX.ElementAttributesProperty [symbol]
427
426
let _jsxElementPropertiesName: string;
427
+ let _hasComputedJsxElementPropertiesName = false;
428
428
let _jsxElementChildrenPropertyName: string;
429
+ let _hasComputedJsxElementChildrenPropertyName = false;
429
430
430
431
/** Things we lazy load from the JSX namespace */
431
432
const jsxTypes = createMap<Type>();
433
+
432
434
const JsxNames = {
433
435
JSX: "JSX",
434
436
IntrinsicElements: "IntrinsicElements",
435
437
ElementClass: "ElementClass",
436
438
ElementAttributesPropertyNameContainer: "ElementAttributesProperty",
439
+ ElementChildrenAttributeNameContainer: "ElementChildrenAttribute",
437
440
Element: "Element",
438
441
IntrinsicAttributes: "IntrinsicAttributes",
439
442
IntrinsicClassAttributes: "IntrinsicClassAttributes"
@@ -12696,7 +12699,7 @@ namespace ts {
12696
12699
else if (node.parent.kind === SyntaxKind.JsxElement) {
12697
12700
// JSX expression is in children of JSX Element, we will look for an "children" atttribute (we get the name from JSX.ElementAttributesProperty)
12698
12701
const jsxChildrenPropertyName = getJsxElementChildrenPropertyname();
12699
- return jsxChildrenPropertyName ? getTypeOfPropertyOfType(attributesType, jsxChildrenPropertyName) : anyType;
12702
+ return jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ? getTypeOfPropertyOfType(attributesType, jsxChildrenPropertyName) : anyType;
12700
12703
}
12701
12704
else {
12702
12705
// JSX expression is in JSX spread attribute
@@ -13361,7 +13364,7 @@ namespace ts {
13361
13364
// Error if there is a attribute named "children" and children element.
13362
13365
// This is because children element will overwrite the value from attributes
13363
13366
const jsxChildrenPropertyName = getJsxElementChildrenPropertyname();
13364
- if (jsxChildrenPropertyName) {
13367
+ if (jsxChildrenPropertyName && jsxChildrenPropertyName !== "" ) {
13365
13368
if (attributesTable.has(jsxChildrenPropertyName)) {
13366
13369
error(attributes, Diagnostics._0_are_specified_twice_The_attribute_named_0_will_be_overwritten, jsxChildrenPropertyName);
13367
13370
}
@@ -13474,14 +13477,34 @@ namespace ts {
13474
13477
return getUnionType(map(signatures, getReturnTypeOfSignature), /*subtypeReduction*/ true);
13475
13478
}
13476
13479
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
+ }
13483
13506
}
13484
- return _jsxElementAttribPropInterfaceSymbol ;
13507
+ return undefined ;
13485
13508
}
13486
13509
13487
13510
/// e.g. "props" for React.d.ts,
@@ -13490,66 +13513,18 @@ namespace ts {
13490
13513
/// or '' if it has 0 properties (which means every
13491
13514
/// non-intrinsic elements' attributes type is the element instance type)
13492
13515
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);
13527
13519
}
13528
13520
13529
13521
return _jsxElementPropertiesName;
13530
13522
}
13531
13523
13532
13524
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);
13553
13528
}
13554
13529
13555
13530
return _jsxElementChildrenPropertyName;
0 commit comments