mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-30 01:04:49 -05:00
Enforce a size limit in getSpreadType
When a union is spread into a union, the sizes are multiplied, potentially resulting in an enormous union (especially if there are repeated spreads). This check detects cases that used to run out of memory. Fixes #40754
This commit is contained in:
@@ -14458,14 +14458,14 @@ namespace ts {
|
||||
if (merged) {
|
||||
return getSpreadType(merged, right, symbol, objectFlags, readonly);
|
||||
}
|
||||
return mapType(left, t => getSpreadType(t, right, symbol, objectFlags, readonly));
|
||||
return errorTypeIfTooLarge() ?? mapType(left, t => getSpreadType(t, right, symbol, objectFlags, readonly));
|
||||
}
|
||||
if (right.flags & TypeFlags.Union) {
|
||||
const merged = tryMergeUnionOfObjectTypeAndEmptyObject(right as UnionType, readonly);
|
||||
if (merged) {
|
||||
return getSpreadType(left, merged, symbol, objectFlags, readonly);
|
||||
}
|
||||
return mapType(right, t => getSpreadType(left, t, symbol, objectFlags, readonly));
|
||||
return errorTypeIfTooLarge() ?? mapType(right, t => getSpreadType(left, t, symbol, objectFlags, readonly));
|
||||
}
|
||||
if (right.flags & (TypeFlags.BooleanLike | TypeFlags.NumberLike | TypeFlags.BigIntLike | TypeFlags.StringLike | TypeFlags.EnumLike | TypeFlags.NonPrimitive | TypeFlags.Index)) {
|
||||
return left;
|
||||
@@ -14544,6 +14544,17 @@ namespace ts {
|
||||
getIndexInfoWithReadonly(numberIndexInfo, readonly));
|
||||
spread.objectFlags |= ObjectFlags.ObjectLiteral | ObjectFlags.ContainsObjectOrArrayLiteral | ObjectFlags.ContainsSpread | objectFlags;
|
||||
return spread;
|
||||
|
||||
function errorTypeIfTooLarge(): Type | undefined {
|
||||
if (left.flags & right.flags & TypeFlags.Union) {
|
||||
const resultSize = (left as UnionType).types.length * (right as UnionType).types.length;
|
||||
if (resultSize > 100000) {
|
||||
tracing.instant(tracing.Phase.Check, "getSpreadType_DepthLimit", { leftId: left.id, rightId: right.id });
|
||||
error(currentNode, Diagnostics.Spread_expression_produces_a_union_type_that_is_too_complex_to_represent);
|
||||
return errorType;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** We approximate own properties as non-methods plus methods that are inside the object literal */
|
||||
|
||||
@@ -3048,6 +3048,10 @@
|
||||
"category": "Error",
|
||||
"code": 2795
|
||||
},
|
||||
"Spread expression produces a union type that is too complex to represent.": {
|
||||
"category": "Error",
|
||||
"code": 2796
|
||||
},
|
||||
|
||||
"Import declaration '{0}' is using private name '{1}'.": {
|
||||
"category": "Error",
|
||||
|
||||
Reference in New Issue
Block a user