@@ -9840,6 +9840,10 @@ namespace ts {
9840
9840
return symbol ? getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol) : undefined;
9841
9841
}
9842
9842
9843
+ function isNonGenericObjectType(type: Type) {
9844
+ return !!(type.flags & TypeFlags.Object) && !isGenericMappedType(type);
9845
+ }
9846
+
9843
9847
/**
9844
9848
* Since the source of spread types are object literals, which are not binary,
9845
9849
* this function should be called in a left folding style, with left = previous result of getSpreadType
@@ -9868,6 +9872,23 @@ namespace ts {
9868
9872
return left;
9869
9873
}
9870
9874
9875
+ if (isGenericObjectType(left) || isGenericObjectType(right)) {
9876
+ if (isEmptyObjectType(left)) {
9877
+ return right;
9878
+ }
9879
+ // When the left type is an intersection, we may need to merge the last constituent of the
9880
+ // intersection with the right type. For example when the left type is 'T & { a: string }'
9881
+ // and the right type is '{ b: string }' we produce 'T & { a: string, b: string }'.
9882
+ if (left.flags & TypeFlags.Intersection) {
9883
+ const types = (<IntersectionType>left).types;
9884
+ const lastLeft = types[types.length - 1];
9885
+ if (isNonGenericObjectType(lastLeft) && isNonGenericObjectType(right)) {
9886
+ return getIntersectionType(concatenate(types.slice(0, types.length - 1), [getSpreadType(lastLeft, right, symbol, typeFlags, objectFlags)]));
9887
+ }
9888
+ }
9889
+ return getIntersectionType([left, right]);
9890
+ }
9891
+
9871
9892
const members = createSymbolTable();
9872
9893
const skippedPrivateMembers = createUnderscoreEscapedMap<boolean>();
9873
9894
let stringIndexInfo: IndexInfo | undefined;
@@ -17697,9 +17718,8 @@ namespace ts {
17697
17718
}
17698
17719
17699
17720
function isValidSpreadType(type: Type): boolean {
17700
- return !!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.NonPrimitive) ||
17721
+ return !!(type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.NonPrimitive | TypeFlags.Object | TypeFlags.InstantiableNonPrimitive ) ||
17701
17722
getFalsyFlags(type) & TypeFlags.DefinitelyFalsy && isValidSpreadType(removeDefinitelyFalsyTypes(type)) ||
17702
- type.flags & TypeFlags.Object && !isGenericMappedType(type) ||
17703
17723
type.flags & TypeFlags.UnionOrIntersection && every((<UnionOrIntersectionType>type).types, isValidSpreadType));
17704
17724
}
17705
17725
0 commit comments