@@ -13481,7 +13481,13 @@ namespace ts {
13481
13481
// JSX expression can appear in two position : JSX Element's children or JSX attribute
13482
13482
const jsxAttributes = isJsxAttributeLike(node.parent) ?
13483
13483
node.parent.parent :
13484
- node.parent.openingElement.attributes; // node.parent is JsxElement
13484
+ isJsxElement(node.parent) ?
13485
+ node.parent.openingElement.attributes :
13486
+ undefined; // node.parent is JsxFragment with no attributes
13487
+
13488
+ if (!jsxAttributes) {
13489
+ return undefined; // don't check children of a fragment
13490
+ }
13485
13491
13486
13492
// When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
13487
13493
// which is a type of the parameter of the signature we are trying out.
@@ -14061,13 +14067,13 @@ namespace ts {
14061
14067
}
14062
14068
14063
14069
function checkJsxSelfClosingElement(node: JsxSelfClosingElement): Type {
14064
- checkJsxOpeningLikeElement (node);
14070
+ checkJsxOpeningLikeElementOrOpeningFragment (node);
14065
14071
return getJsxGlobalElementType() || anyType;
14066
14072
}
14067
14073
14068
14074
function checkJsxElement(node: JsxElement): Type {
14069
14075
// Check attributes
14070
- checkJsxOpeningLikeElement (node.openingElement);
14076
+ checkJsxOpeningLikeElementOrOpeningFragment (node.openingElement);
14071
14077
14072
14078
// Perform resolution on the closing tag so that rename/go to definition/etc work
14073
14079
if (isJsxIntrinsicIdentifier(node.closingElement.tagName)) {
@@ -14080,6 +14086,16 @@ namespace ts {
14080
14086
return getJsxGlobalElementType() || anyType;
14081
14087
}
14082
14088
14089
+ function checkJsxFragment(node: JsxFragment): Type {
14090
+ checkJsxOpeningLikeElementOrOpeningFragment(node.openingFragment);
14091
+
14092
+ if (compilerOptions.jsx === JsxEmit.React && compilerOptions.jsxFactory) {
14093
+ error(node, Diagnostics.JSX_fragment_is_not_supported_when_using_jsxFactory);
14094
+ }
14095
+
14096
+ return getJsxGlobalElementType() || anyType;
14097
+ }
14098
+
14083
14099
/**
14084
14100
* Returns true iff the JSX element name would be a valid JS identifier, ignoring restrictions about keywords not being identifiers
14085
14101
*/
@@ -14184,19 +14200,7 @@ namespace ts {
14184
14200
const parent = openingLikeElement.parent.kind === SyntaxKind.JsxElement ? openingLikeElement.parent as JsxElement : undefined;
14185
14201
// We have to check that openingElement of the parent is the one we are visiting as this may not be true for selfClosingElement
14186
14202
if (parent && parent.openingElement === openingLikeElement && parent.children.length > 0) {
14187
- const childrenTypes: Type[] = [];
14188
- for (const child of (parent as JsxElement).children) {
14189
- // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that
14190
- // because then type of children property will have constituent of string type.
14191
- if (child.kind === SyntaxKind.JsxText) {
14192
- if (!child.containsOnlyWhiteSpaces) {
14193
- childrenTypes.push(stringType);
14194
- }
14195
- }
14196
- else {
14197
- childrenTypes.push(checkExpression(child, checkMode));
14198
- }
14199
- }
14203
+ const childrenTypes: Type[] = checkJsxChildren(parent as JsxElement, checkMode);
14200
14204
14201
14205
if (!hasSpreadAnyType && jsxChildrenPropertyName && jsxChildrenPropertyName !== "") {
14202
14206
// Error if there is a attribute named "children" explicitly specified and children element.
@@ -14236,6 +14240,23 @@ namespace ts {
14236
14240
}
14237
14241
}
14238
14242
14243
+ function checkJsxChildren(node: JsxElement | JsxFragment, checkMode?: CheckMode) {
14244
+ const childrenTypes: Type[] = [];
14245
+ for (const child of node.children) {
14246
+ // In React, JSX text that contains only whitespaces will be ignored so we don't want to type-check that
14247
+ // because then type of children property will have constituent of string type.
14248
+ if (child.kind === SyntaxKind.JsxText) {
14249
+ if (!child.containsOnlyWhiteSpaces) {
14250
+ childrenTypes.push(stringType);
14251
+ }
14252
+ }
14253
+ else {
14254
+ childrenTypes.push(checkExpression(child, checkMode));
14255
+ }
14256
+ }
14257
+ return childrenTypes;
14258
+ }
14259
+
14239
14260
/**
14240
14261
* Check attributes property of opening-like element. This function is called during chooseOverload to get call signature of a JSX opening-like element.
14241
14262
* (See "checkApplicableSignatureForJsxOpeningLikeElement" for how the function is used)
@@ -14743,14 +14764,19 @@ namespace ts {
14743
14764
}
14744
14765
}
14745
14766
14746
- function checkJsxOpeningLikeElement(node: JsxOpeningLikeElement) {
14747
- checkGrammarJsxElement(node);
14767
+ function checkJsxOpeningLikeElementOrOpeningFragment(node: JsxOpeningLikeElement | JsxOpeningFragment) {
14768
+ const isNodeOpeningLikeElement = isJsxOpeningLikeElement(node);
14769
+
14770
+ if (isNodeOpeningLikeElement) {
14771
+ checkGrammarJsxElement(<JsxOpeningLikeElement>node);
14772
+ }
14748
14773
checkJsxPreconditions(node);
14749
14774
// The reactNamespace/jsxFactory's root symbol should be marked as 'used' so we don't incorrectly elide its import.
14750
14775
// And if there is no reactNamespace/jsxFactory's symbol in scope when targeting React emit, we should issue an error.
14751
14776
const reactRefErr = diagnostics && compilerOptions.jsx === JsxEmit.React ? Diagnostics.Cannot_find_name_0 : undefined;
14752
14777
const reactNamespace = getJsxNamespace();
14753
- const reactSym = resolveName(node.tagName, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true);
14778
+ const reactLocation = isNodeOpeningLikeElement ? (<JsxOpeningLikeElement>node).tagName : node;
14779
+ const reactSym = resolveName(reactLocation, reactNamespace, SymbolFlags.Value, reactRefErr, reactNamespace, /*isUse*/ true);
14754
14780
if (reactSym) {
14755
14781
// Mark local symbol as referenced here because it might not have been marked
14756
14782
// if jsx emit was not react as there wont be error being emitted
@@ -14762,7 +14788,12 @@ namespace ts {
14762
14788
}
14763
14789
}
14764
14790
14765
- checkJsxAttributesAssignableToTagNameAttributes(node);
14791
+ if (isNodeOpeningLikeElement) {
14792
+ checkJsxAttributesAssignableToTagNameAttributes(<JsxOpeningLikeElement>node);
14793
+ }
14794
+ else {
14795
+ checkJsxChildren((node as JsxOpeningFragment).parent);
14796
+ }
14766
14797
}
14767
14798
14768
14799
/**
@@ -18526,6 +18557,8 @@ namespace ts {
18526
18557
return checkJsxElement(<JsxElement>node);
18527
18558
case SyntaxKind.JsxSelfClosingElement:
18528
18559
return checkJsxSelfClosingElement(<JsxSelfClosingElement>node);
18560
+ case SyntaxKind.JsxFragment:
18561
+ return checkJsxFragment(<JsxFragment>node);
18529
18562
case SyntaxKind.JsxAttributes:
18530
18563
return checkJsxAttributes(<JsxAttributes>node, checkMode);
18531
18564
case SyntaxKind.JsxOpeningElement:
0 commit comments