Skip to content

Commit de68f06

Browse files
committed
Set flags on fresh object types from getSpreadType
Previously, getSpreadType didn't set any flags and relied on its callers to do so. This was error-prone because getSpreadType often returns non-fresh types.
1 parent 517dbf3 commit de68f06

File tree

1 file changed

+16
-19
lines changed

1 file changed

+16
-19
lines changed

src/compiler/checker.ts

+16-19
Original file line numberDiff line numberDiff line change
@@ -7846,7 +7846,7 @@ namespace ts {
78467846
* this function should be called in a left folding style, with left = previous result of getSpreadType
78477847
* and right = the new element to be spread.
78487848
*/
7849-
function getSpreadType(left: Type, right: Type): Type {
7849+
function getSpreadType(left: Type, right: Type, symbol: Symbol, propagatedFlags: TypeFlags): Type {
78507850
if (left.flags & TypeFlags.Any || right.flags & TypeFlags.Any) {
78517851
return anyType;
78527852
}
@@ -7857,10 +7857,10 @@ namespace ts {
78577857
return left;
78587858
}
78597859
if (left.flags & TypeFlags.Union) {
7860-
return mapType(left, t => getSpreadType(t, right));
7860+
return mapType(left, t => getSpreadType(t, right, symbol, propagatedFlags));
78617861
}
78627862
if (right.flags & TypeFlags.Union) {
7863-
return mapType(right, t => getSpreadType(left, t));
7863+
return mapType(right, t => getSpreadType(left, t, symbol, propagatedFlags));
78647864
}
78657865
if (right.flags & TypeFlags.NonPrimitive) {
78667866
return nonPrimitiveType;
@@ -7918,7 +7918,13 @@ namespace ts {
79187918
members.set(leftProp.escapedName, getNonReadonlySymbol(leftProp));
79197919
}
79207920
}
7921-
return createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
7921+
7922+
const spread = createAnonymousType(undefined, members, emptyArray, emptyArray, stringIndexInfo, numberIndexInfo);
7923+
spread.flags |= propagatedFlags;
7924+
spread.flags |= TypeFlags.FreshLiteral;
7925+
(spread as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral;
7926+
spread.symbol = symbol;
7927+
return spread;
79227928
}
79237929

79247930
function getNonReadonlySymbol(prop: Symbol) {
@@ -13858,7 +13864,7 @@ namespace ts {
1385813864
checkExternalEmitHelpers(memberDecl, ExternalEmitHelpers.Assign);
1385913865
}
1386013866
if (propertiesArray.length > 0) {
13861-
spread = getSpreadType(spread, createObjectLiteralType());
13867+
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags);
1386213868
propertiesArray = [];
1386313869
propertiesTable = createSymbolTable();
1386413870
hasComputedStringProperty = false;
@@ -13870,7 +13876,7 @@ namespace ts {
1387013876
error(memberDecl, Diagnostics.Spread_types_may_only_be_created_from_object_types);
1387113877
return unknownType;
1387213878
}
13873-
spread = getSpreadType(spread, type);
13879+
spread = getSpreadType(spread, type, node.symbol, propagatedFlags);
1387413880
offset = i + 1;
1387513881
continue;
1387613882
}
@@ -13915,17 +13921,8 @@ namespace ts {
1391513921

1391613922
if (spread !== emptyObjectType) {
1391713923
if (propertiesArray.length > 0) {
13918-
spread = getSpreadType(spread, createObjectLiteralType());
13924+
spread = getSpreadType(spread, createObjectLiteralType(), node.symbol, propagatedFlags);
1391913925
}
13920-
// only set the symbol and flags if this is a (fresh) object type
13921-
forEachType(spread, t => {
13922-
if (t.flags & TypeFlags.Object) {
13923-
t.flags |= propagatedFlags;
13924-
t.flags |= TypeFlags.FreshLiteral;
13925-
(t as ObjectType).objectFlags |= ObjectFlags.ObjectLiteral;
13926-
t.symbol = node.symbol;
13927-
}
13928-
});
1392913926
return spread;
1393013927
}
1393113928

@@ -14045,7 +14042,7 @@ namespace ts {
1404514042
else {
1404614043
Debug.assert(attributeDecl.kind === SyntaxKind.JsxSpreadAttribute);
1404714044
if (attributesArray.length > 0) {
14048-
spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable));
14045+
spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0);
1404914046
attributesArray = [];
1405014047
attributesTable = createSymbolTable();
1405114048
}
@@ -14054,7 +14051,7 @@ namespace ts {
1405414051
hasSpreadAnyType = true;
1405514052
}
1405614053
if (isValidSpreadType(exprType)) {
14057-
spread = getSpreadType(spread, exprType);
14054+
spread = getSpreadType(spread, exprType, openingLikeElement.symbol, /*propagatedFlags*/ 0);
1405814055
}
1405914056
else {
1406014057
typeToIntersect = typeToIntersect ? getIntersectionType([typeToIntersect, exprType]) : exprType;
@@ -14065,7 +14062,7 @@ namespace ts {
1406514062
if (!hasSpreadAnyType) {
1406614063
if (spread !== emptyObjectType) {
1406714064
if (attributesArray.length > 0) {
14068-
spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable));
14065+
spread = getSpreadType(spread, createJsxAttributesType(attributes.symbol, attributesTable), openingLikeElement.symbol, /*propagatedFlags*/ 0);
1406914066
}
1407014067
attributesArray = getPropertiesOfType(spread);
1407114068
}

0 commit comments

Comments
 (0)