@@ -4464,10 +4464,9 @@ namespace ts {
44644464 names.set(getTextOfPropertyName(name), true);
44654465 }
44664466 for (const prop of getPropertiesOfType(source)) {
4467- const inNamesToRemove = names.has(prop.escapedName);
4468- const isPrivate = getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected);
4469- const isSetOnlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor);
4470- if (!inNamesToRemove && !isPrivate && !isClassMethod(prop) && !isSetOnlyAccessor) {
4467+ if (!names.has(prop.escapedName)
4468+ && !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected))
4469+ && isSpreadableProperty(prop)) {
44714470 members.set(prop.escapedName, getNonReadonlySymbol(prop));
44724471 }
44734472 }
@@ -9649,20 +9648,16 @@ namespace ts {
96499648 }
96509649
96519650 for (const rightProp of getPropertiesOfType(right)) {
9652- // we approximate own properties as non-methods plus methods that are inside the object literal
9653- const isSetterWithoutGetter = rightProp.flags & SymbolFlags.SetAccessor && !(rightProp.flags & SymbolFlags.GetAccessor);
96549651 if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) {
96559652 skippedPrivateMembers.set(rightProp.escapedName, true);
96569653 }
9657- else if (!isClassMethod (rightProp) && !isSetterWithoutGetter ) {
9654+ else if (isSpreadableProperty (rightProp)) {
96589655 members.set(rightProp.escapedName, getNonReadonlySymbol(rightProp));
96599656 }
96609657 }
96619658
96629659 for (const leftProp of getPropertiesOfType(left)) {
9663- if (leftProp.flags & SymbolFlags.SetAccessor && !(leftProp.flags & SymbolFlags.GetAccessor)
9664- || skippedPrivateMembers.has(leftProp.escapedName)
9665- || isClassMethod(leftProp)) {
9660+ if (skippedPrivateMembers.has(leftProp.escapedName) || !isSpreadableProperty(leftProp)) {
96669661 continue;
96679662 }
96689663 if (members.has(leftProp.escapedName)) {
@@ -9697,6 +9692,13 @@ namespace ts {
96979692 return spread;
96989693 }
96999694
9695+ /** We approximate own properties as non-methods plus methods that are inside the object literal */
9696+ function isSpreadableProperty(prop: Symbol): boolean {
9697+ return prop.flags & (SymbolFlags.Method | SymbolFlags.GetAccessor)
9698+ ? !prop.declarations.some(decl => isClassLike(decl.parent))
9699+ : !(prop.flags & SymbolFlags.SetAccessor); // Setter without getter is not spreadable
9700+ }
9701+
97009702 function getNonReadonlySymbol(prop: Symbol) {
97019703 if (!isReadonlySymbol(prop)) {
97029704 return prop;
@@ -9717,10 +9719,6 @@ namespace ts {
97179719 return index;
97189720 }
97199721
9720- function isClassMethod(prop: Symbol) {
9721- return prop.flags & SymbolFlags.Method && find(prop.declarations, decl => isClassLike(decl.parent));
9722- }
9723-
97249722 function createLiteralType(flags: TypeFlags, value: string | number, symbol: Symbol | undefined) {
97259723 const type = <LiteralType>createType(flags);
97269724 type.symbol = symbol!;
0 commit comments