Skip to content

Commit 8e2dd38

Browse files
author
Kanchalai Tanglertsampan
committed
Use JSX Attributes to contextually type children property
1 parent f86a730 commit 8e2dd38

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

src/compiler/checker.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12635,6 +12635,35 @@ namespace ts {
1263512635
return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined;
1263612636
}
1263712637

12638+
function getContextualTypeForJsxExpression(node: JsxExpression): Type {
12639+
// JSX expression can appear in two position : JSX Element's children or JSX attribute
12640+
const jsxAttributes = isJsxAttributeLike(node.parent) ?
12641+
node.parent.parent :
12642+
node.parent.openingElement.attributes; // node.parent is JsxElement
12643+
12644+
// When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
12645+
// which is a type of the parameter of the signature we are trying out.
12646+
// If there is no contextual type (e.g. we are trying to resolve stateful component), get attributes type from resolving element's tagName
12647+
const attributesType = getContextualType(jsxAttributes);
12648+
12649+
if (!attributesType || isTypeAny(attributesType)) {
12650+
return undefined;
12651+
}
12652+
12653+
if (isJsxAttribute(node.parent)) {
12654+
// JSX expression is in JSX attribute
12655+
return getTypeOfPropertyOfType(attributesType, (node.parent as JsxAttribute).name.text);
12656+
}
12657+
else if (node.parent.kind === SyntaxKind.JsxElement) {
12658+
// JSX expression is in children of JSX Element, we will look for an atttribute named "chidlren"
12659+
return getTypeOfPropertyOfType(attributesType, jsxChildrenPropertyName);
12660+
}
12661+
else {
12662+
// JSX expression is in JSX spread attribute
12663+
return attributesType;
12664+
}
12665+
}
12666+
1263812667
function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) {
1263912668
// When we trying to resolve JsxOpeningLikeElement as a stateless function element, we will already give its attributes a contextual type
1264012669
// which is a type of the parameter of the signature we are trying out.
@@ -12718,7 +12747,7 @@ namespace ts {
1271812747
case SyntaxKind.ParenthesizedExpression:
1271912748
return getContextualType(<ParenthesizedExpression>parent);
1272012749
case SyntaxKind.JsxExpression:
12721-
return getContextualType(<JsxExpression>parent);
12750+
return getContextualTypeForJsxExpression(<JsxExpression>parent);
1272212751
case SyntaxKind.JsxAttribute:
1272312752
case SyntaxKind.JsxSpreadAttribute:
1272412753
return getContextualTypeForJsxAttribute(<JsxAttribute | JsxSpreadAttribute>parent);

0 commit comments

Comments
 (0)