diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 5d57e9d202..00bddd2f7b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7464,24 +7464,22 @@ namespace ts { return node === conditional.whenTrue || node === conditional.whenFalse ? getContextualType(conditional) : undefined; } - function getContextualTypeForJsxExpression(expr: JsxExpression | JsxSpreadAttribute): Type { - // Contextual type only applies to JSX expressions that are in attribute assignments (not in 'Children' positions) - if (expr.parent.kind === SyntaxKind.JsxAttribute) { - const attrib = expr.parent; - const attrsType = getJsxElementAttributesType(attrib.parent); + function getContextualTypeForJsxAttribute(attribute: JsxAttribute | JsxSpreadAttribute) { + const kind = attribute.kind; + const jsxElement = attribute.parent as JsxOpeningLikeElement; + const attrsType = getJsxElementAttributesType(jsxElement); + + if (attribute.kind === SyntaxKind.JsxAttribute) { if (!attrsType || isTypeAny(attrsType)) { return undefined; } - else { - return getTypeOfPropertyOfType(attrsType, attrib.name.text); - } + return getTypeOfPropertyOfType(attrsType, (attribute as JsxAttribute).name.text); + } + else if (attribute.kind === SyntaxKind.JsxSpreadAttribute) { + return attrsType; } - if (expr.kind === SyntaxKind.JsxSpreadAttribute) { - return getJsxElementAttributesType(expr.parent); - } - - return undefined; + Debug.fail(`Expected JsxAttribute or JsxSpreadAttribute, got ts.SyntaxKind[${kind}]`); } // Return the contextual type for a given expression node. During overload resolution, a contextual type may temporarily @@ -7549,8 +7547,10 @@ namespace ts { case SyntaxKind.ParenthesizedExpression: return getContextualType(parent); case SyntaxKind.JsxExpression: + return getContextualType(parent); + case SyntaxKind.JsxAttribute: case SyntaxKind.JsxSpreadAttribute: - return getContextualTypeForJsxExpression(parent); + return getContextualTypeForJsxAttribute(parent); } return undefined; }