Fixing react defaultize+generic default props interaction (#27088)

* Add repro for fixed issue

* Fix JSX propagating flags and contextual types

* Accept slightly changed baselines

* Add modern react.d.ts and regression test
This commit is contained in:
Wesley Wigham
2018-09-14 14:18:47 -07:00
committed by GitHub
parent bce34ada8f
commit 4eb59a2d77
14 changed files with 3261 additions and 16 deletions

View File

@@ -17361,12 +17361,14 @@ namespace ts {
let hasSpreadAnyType = false;
let typeToIntersect: Type | undefined;
let explicitlySpecifyChildrenAttribute = false;
let propagatingFlags: TypeFlags = 0;
const jsxChildrenPropertyName = getJsxElementChildrenPropertyName(getJsxNamespaceAt(openingLikeElement));
for (const attributeDecl of attributes.properties) {
const member = attributeDecl.symbol;
if (isJsxAttribute(attributeDecl)) {
const exprType = checkJsxAttribute(attributeDecl, checkMode);
propagatingFlags |= (exprType.flags & TypeFlags.PropagatingFlags);
const attributeSymbol = createSymbol(SymbolFlags.Property | SymbolFlags.Transient | member.flags, member.escapedName);
attributeSymbol.declarations = member.declarations;
@@ -17384,7 +17386,7 @@ namespace ts {
else {
Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute);
if (attributesTable.size > 0) {
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes);
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, propagatingFlags, ObjectFlags.JsxAttributes);
attributesTable = createSymbolTable();
}
const exprType = checkExpressionCached(attributeDecl.expression, checkMode);
@@ -17392,7 +17394,7 @@ namespace ts {
hasSpreadAnyType = true;
}
if (isValidSpreadType(exprType)) {
spread = getSpreadType(spread, exprType, openingLikeElement.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes);
spread = getSpreadType(spread, exprType, openingLikeElement.symbol, propagatingFlags, ObjectFlags.JsxAttributes);
}
else {
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
@@ -17402,7 +17404,7 @@ namespace ts {
if (!hasSpreadAnyType) {
if (attributesTable.size > 0) {
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes);
spread = getSpreadType(spread, createJsxAttributesType(), attributes.symbol, propagatingFlags, ObjectFlags.JsxAttributes);
}
}
@@ -17428,7 +17430,7 @@ namespace ts {
const childPropMap = createSymbolTable();
childPropMap.set(jsxChildrenPropertyName, childrenPropSymbol);
spread = getSpreadType(spread, createAnonymousType(attributes.symbol, childPropMap, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined),
attributes.symbol, /*typeFlags*/ 0, ObjectFlags.JsxAttributes);
attributes.symbol, propagatingFlags, ObjectFlags.JsxAttributes);
}
}
@@ -17448,7 +17450,7 @@ namespace ts {
*/
function createJsxAttributesType() {
const result = createAnonymousType(attributes.symbol, attributesTable, emptyArray, emptyArray, /*stringIndexInfo*/ undefined, /*numberIndexInfo*/ undefined);
result.flags |= TypeFlags.ContainsObjectLiteral;
result.flags |= (propagatingFlags |= TypeFlags.ContainsObjectLiteral);
result.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.JsxAttributes;
return result;
}
@@ -21957,7 +21959,7 @@ namespace ts {
}
function getContextNode(node: Expression): Node {
if (node.kind === SyntaxKind.JsxAttributes) {
if (node.kind === SyntaxKind.JsxAttributes && !isJsxSelfClosingElement(node.parent)) {
return node.parent.parent; // Needs to be the root JsxElement, so it encompasses the attributes _and_ the children (which are essentially part of the attributes)
}
return node;