Don't include class getter in spread type (#26287)

* Don't include class getter in spread type

* Code review
This commit is contained in:
Andy
2018-08-09 15:34:29 -07:00
committed by GitHub
parent 55a620c433
commit 639fdcc916
7 changed files with 285 additions and 141 deletions

View File

@@ -4464,10 +4464,9 @@ namespace ts {
names.set(getTextOfPropertyName(name), true);
}
for (const prop of getPropertiesOfType(source)) {
const inNamesToRemove = names.has(prop.escapedName);
const isPrivate = getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected);
const isSetOnlyAccessor = prop.flags & SymbolFlags.SetAccessor && !(prop.flags & SymbolFlags.GetAccessor);
if (!inNamesToRemove && !isPrivate && !isClassMethod(prop) && !isSetOnlyAccessor) {
if (!names.has(prop.escapedName)
&& !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected))
&& isSpreadableProperty(prop)) {
members.set(prop.escapedName, getNonReadonlySymbol(prop));
}
}
@@ -9649,20 +9648,16 @@ namespace ts {
}
for (const rightProp of getPropertiesOfType(right)) {
// we approximate own properties as non-methods plus methods that are inside the object literal
const isSetterWithoutGetter = rightProp.flags & SymbolFlags.SetAccessor && !(rightProp.flags & SymbolFlags.GetAccessor);
if (getDeclarationModifierFlagsFromSymbol(rightProp) & (ModifierFlags.Private | ModifierFlags.Protected)) {
skippedPrivateMembers.set(rightProp.escapedName, true);
}
else if (!isClassMethod(rightProp) && !isSetterWithoutGetter) {
else if (isSpreadableProperty(rightProp)) {
members.set(rightProp.escapedName, getNonReadonlySymbol(rightProp));
}
}
for (const leftProp of getPropertiesOfType(left)) {
if (leftProp.flags & SymbolFlags.SetAccessor && !(leftProp.flags & SymbolFlags.GetAccessor)
|| skippedPrivateMembers.has(leftProp.escapedName)
|| isClassMethod(leftProp)) {
if (skippedPrivateMembers.has(leftProp.escapedName) || !isSpreadableProperty(leftProp)) {
continue;
}
if (members.has(leftProp.escapedName)) {
@@ -9697,6 +9692,13 @@ namespace ts {
return spread;
}
/** We approximate own properties as non-methods plus methods that are inside the object literal */
function isSpreadableProperty(prop: Symbol): boolean {
return prop.flags & (SymbolFlags.Method | SymbolFlags.GetAccessor)
? !prop.declarations.some(decl => isClassLike(decl.parent))
: !(prop.flags & SymbolFlags.SetAccessor); // Setter without getter is not spreadable
}
function getNonReadonlySymbol(prop: Symbol) {
if (!isReadonlySymbol(prop)) {
return prop;
@@ -9717,10 +9719,6 @@ namespace ts {
return index;
}
function isClassMethod(prop: Symbol) {
return prop.flags & SymbolFlags.Method && find(prop.declarations, decl => isClassLike(decl.parent));
}
function createLiteralType(flags: TypeFlags, value: string | number, symbol: Symbol | undefined) {
const type = <LiteralType>createType(flags);
type.symbol = symbol!;