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!;

View File

@@ -175,7 +175,7 @@ var removable = new Removable();
var { removed, ...removableRest } = removable;
>removed : string
>removableRest : { both: number; remainder: string; }
>removableRest : { remainder: string; }
>removable : Removable
var i: I = removable;

View File

@@ -1,10 +1,21 @@
tests/cases/conformance/types/spread/spreadMethods.ts(7,4): error TS2339: Property 'm' does not exist on type '{ p: number; }'.
tests/cases/conformance/types/spread/spreadMethods.ts(9,5): error TS2339: Property 'm' does not exist on type '{ p: number; }'.
tests/cases/conformance/types/spread/spreadMethods.ts(16,4): error TS2339: Property 'm' does not exist on type '{ p: number; }'.
tests/cases/conformance/types/spread/spreadMethods.ts(17,4): error TS2339: Property 'g' does not exist on type '{ p: number; }'.
tests/cases/conformance/types/spread/spreadMethods.ts(19,5): error TS2339: Property 'm' does not exist on type '{ p: number; }'.
tests/cases/conformance/types/spread/spreadMethods.ts(20,5): error TS2339: Property 'g' does not exist on type '{ p: number; }'.
==== tests/cases/conformance/types/spread/spreadMethods.ts (2 errors) ====
class K { p = 12; m() { } }
interface I { p: number, m(): void }
==== tests/cases/conformance/types/spread/spreadMethods.ts (4 errors) ====
class K {
p = 12;
m() { }
get g() { return 0; }
}
interface I {
p: number;
m(): void;
readonly g: number;
}
let k = new K()
let sk = { ...k };
let ssk = { ...k, ...k };
@@ -12,22 +23,34 @@ tests/cases/conformance/types/spread/spreadMethods.ts(9,5): error TS2339: Proper
sk.m(); // error
~
!!! error TS2339: Property 'm' does not exist on type '{ p: number; }'.
sk.g; // error
~
!!! error TS2339: Property 'g' does not exist on type '{ p: number; }'.
ssk.p;
ssk.m(); // error
~
!!! error TS2339: Property 'm' does not exist on type '{ p: number; }'.
let i: I = { p: 12, m() { } };
ssk.g; // error
~
!!! error TS2339: Property 'g' does not exist on type '{ p: number; }'.
let i: I = { p: 12, m() { }, get g() { return 0; } };
let si = { ...i };
let ssi = { ...i, ...i };
si.p;
si.m(); // ok
si.g; // ok
ssi.p;
ssi.m(); // ok
let o = { p: 12, m() { } };
ssi.g; // ok
let o = { p: 12, m() { }, get g() { return 0; } };
let so = { ...o };
let sso = { ...o, ...o };
so.p;
so.m(); // ok
so.g; // ok
sso.p;
sso.m(); // ok
sso.g; // ok

View File

@@ -1,66 +1,78 @@
//// [spreadMethods.ts]
class K { p = 12; m() { } }
interface I { p: number, m(): void }
class K {
p = 12;
m() { }
get g() { return 0; }
}
interface I {
p: number;
m(): void;
readonly g: number;
}
let k = new K()
let sk = { ...k };
let ssk = { ...k, ...k };
sk.p;
sk.m(); // error
sk.g; // error
ssk.p;
ssk.m(); // error
let i: I = { p: 12, m() { } };
ssk.g; // error
let i: I = { p: 12, m() { }, get g() { return 0; } };
let si = { ...i };
let ssi = { ...i, ...i };
si.p;
si.m(); // ok
si.g; // ok
ssi.p;
ssi.m(); // ok
let o = { p: 12, m() { } };
ssi.g; // ok
let o = { p: 12, m() { }, get g() { return 0; } };
let so = { ...o };
let sso = { ...o, ...o };
so.p;
so.m(); // ok
so.g; // ok
sso.p;
sso.m(); // ok
sso.g; // ok
//// [spreadMethods.js]
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var K = /** @class */ (function () {
function K() {
class K {
constructor() {
this.p = 12;
}
K.prototype.m = function () { };
return K;
}());
var k = new K();
var sk = __assign({}, k);
var ssk = __assign({}, k, k);
m() { }
get g() { return 0; }
}
let k = new K();
let sk = { ...k };
let ssk = { ...k, ...k };
sk.p;
sk.m(); // error
sk.g; // error
ssk.p;
ssk.m(); // error
var i = { p: 12, m: function () { } };
var si = __assign({}, i);
var ssi = __assign({}, i, i);
ssk.g; // error
let i = { p: 12, m() { }, get g() { return 0; } };
let si = { ...i };
let ssi = { ...i, ...i };
si.p;
si.m(); // ok
si.g; // ok
ssi.p;
ssi.m(); // ok
var o = { p: 12, m: function () { } };
var so = __assign({}, o);
var sso = __assign({}, o, o);
ssi.g; // ok
let o = { p: 12, m() { }, get g() { return 0; } };
let so = { ...o };
let sso = { ...o, ...o };
so.p;
so.m(); // ok
so.g; // ok
sso.p;
sso.m(); // ok
sso.g; // ok

View File

@@ -1,109 +1,152 @@
=== tests/cases/conformance/types/spread/spreadMethods.ts ===
class K { p = 12; m() { } }
class K {
>K : Symbol(K, Decl(spreadMethods.ts, 0, 0))
>p : Symbol(K.p, Decl(spreadMethods.ts, 0, 9))
>m : Symbol(K.m, Decl(spreadMethods.ts, 0, 17))
interface I { p: number, m(): void }
>I : Symbol(I, Decl(spreadMethods.ts, 0, 27))
>p : Symbol(I.p, Decl(spreadMethods.ts, 1, 13))
>m : Symbol(I.m, Decl(spreadMethods.ts, 1, 24))
p = 12;
>p : Symbol(K.p, Decl(spreadMethods.ts, 0, 9))
m() { }
>m : Symbol(K.m, Decl(spreadMethods.ts, 1, 11))
get g() { return 0; }
>g : Symbol(K.g, Decl(spreadMethods.ts, 2, 11))
}
interface I {
>I : Symbol(I, Decl(spreadMethods.ts, 4, 1))
p: number;
>p : Symbol(I.p, Decl(spreadMethods.ts, 5, 13))
m(): void;
>m : Symbol(I.m, Decl(spreadMethods.ts, 6, 14))
readonly g: number;
>g : Symbol(I.g, Decl(spreadMethods.ts, 7, 14))
}
let k = new K()
>k : Symbol(k, Decl(spreadMethods.ts, 2, 3))
>k : Symbol(k, Decl(spreadMethods.ts, 11, 3))
>K : Symbol(K, Decl(spreadMethods.ts, 0, 0))
let sk = { ...k };
>sk : Symbol(sk, Decl(spreadMethods.ts, 3, 3))
>k : Symbol(k, Decl(spreadMethods.ts, 2, 3))
>sk : Symbol(sk, Decl(spreadMethods.ts, 12, 3))
>k : Symbol(k, Decl(spreadMethods.ts, 11, 3))
let ssk = { ...k, ...k };
>ssk : Symbol(ssk, Decl(spreadMethods.ts, 4, 3))
>k : Symbol(k, Decl(spreadMethods.ts, 2, 3))
>k : Symbol(k, Decl(spreadMethods.ts, 2, 3))
>ssk : Symbol(ssk, Decl(spreadMethods.ts, 13, 3))
>k : Symbol(k, Decl(spreadMethods.ts, 11, 3))
>k : Symbol(k, Decl(spreadMethods.ts, 11, 3))
sk.p;
>sk.p : Symbol(K.p, Decl(spreadMethods.ts, 0, 9))
>sk : Symbol(sk, Decl(spreadMethods.ts, 3, 3))
>sk : Symbol(sk, Decl(spreadMethods.ts, 12, 3))
>p : Symbol(K.p, Decl(spreadMethods.ts, 0, 9))
sk.m(); // error
>sk : Symbol(sk, Decl(spreadMethods.ts, 3, 3))
>sk : Symbol(sk, Decl(spreadMethods.ts, 12, 3))
sk.g; // error
>sk : Symbol(sk, Decl(spreadMethods.ts, 12, 3))
ssk.p;
>ssk.p : Symbol(K.p, Decl(spreadMethods.ts, 0, 9))
>ssk : Symbol(ssk, Decl(spreadMethods.ts, 4, 3))
>ssk : Symbol(ssk, Decl(spreadMethods.ts, 13, 3))
>p : Symbol(K.p, Decl(spreadMethods.ts, 0, 9))
ssk.m(); // error
>ssk : Symbol(ssk, Decl(spreadMethods.ts, 4, 3))
>ssk : Symbol(ssk, Decl(spreadMethods.ts, 13, 3))
let i: I = { p: 12, m() { } };
>i : Symbol(i, Decl(spreadMethods.ts, 9, 3))
>I : Symbol(I, Decl(spreadMethods.ts, 0, 27))
>p : Symbol(p, Decl(spreadMethods.ts, 9, 12))
>m : Symbol(m, Decl(spreadMethods.ts, 9, 19))
ssk.g; // error
>ssk : Symbol(ssk, Decl(spreadMethods.ts, 13, 3))
let i: I = { p: 12, m() { }, get g() { return 0; } };
>i : Symbol(i, Decl(spreadMethods.ts, 21, 3))
>I : Symbol(I, Decl(spreadMethods.ts, 4, 1))
>p : Symbol(p, Decl(spreadMethods.ts, 21, 12))
>m : Symbol(m, Decl(spreadMethods.ts, 21, 19))
>g : Symbol(g, Decl(spreadMethods.ts, 21, 28))
let si = { ...i };
>si : Symbol(si, Decl(spreadMethods.ts, 10, 3))
>i : Symbol(i, Decl(spreadMethods.ts, 9, 3))
>si : Symbol(si, Decl(spreadMethods.ts, 22, 3))
>i : Symbol(i, Decl(spreadMethods.ts, 21, 3))
let ssi = { ...i, ...i };
>ssi : Symbol(ssi, Decl(spreadMethods.ts, 11, 3))
>i : Symbol(i, Decl(spreadMethods.ts, 9, 3))
>i : Symbol(i, Decl(spreadMethods.ts, 9, 3))
>ssi : Symbol(ssi, Decl(spreadMethods.ts, 23, 3))
>i : Symbol(i, Decl(spreadMethods.ts, 21, 3))
>i : Symbol(i, Decl(spreadMethods.ts, 21, 3))
si.p;
>si.p : Symbol(I.p, Decl(spreadMethods.ts, 1, 13))
>si : Symbol(si, Decl(spreadMethods.ts, 10, 3))
>p : Symbol(I.p, Decl(spreadMethods.ts, 1, 13))
>si.p : Symbol(I.p, Decl(spreadMethods.ts, 5, 13))
>si : Symbol(si, Decl(spreadMethods.ts, 22, 3))
>p : Symbol(I.p, Decl(spreadMethods.ts, 5, 13))
si.m(); // ok
>si.m : Symbol(I.m, Decl(spreadMethods.ts, 1, 24))
>si : Symbol(si, Decl(spreadMethods.ts, 10, 3))
>m : Symbol(I.m, Decl(spreadMethods.ts, 1, 24))
>si.m : Symbol(I.m, Decl(spreadMethods.ts, 6, 14))
>si : Symbol(si, Decl(spreadMethods.ts, 22, 3))
>m : Symbol(I.m, Decl(spreadMethods.ts, 6, 14))
si.g; // ok
>si.g : Symbol(g, Decl(spreadMethods.ts, 7, 14))
>si : Symbol(si, Decl(spreadMethods.ts, 22, 3))
>g : Symbol(g, Decl(spreadMethods.ts, 7, 14))
ssi.p;
>ssi.p : Symbol(I.p, Decl(spreadMethods.ts, 1, 13))
>ssi : Symbol(ssi, Decl(spreadMethods.ts, 11, 3))
>p : Symbol(I.p, Decl(spreadMethods.ts, 1, 13))
>ssi.p : Symbol(I.p, Decl(spreadMethods.ts, 5, 13))
>ssi : Symbol(ssi, Decl(spreadMethods.ts, 23, 3))
>p : Symbol(I.p, Decl(spreadMethods.ts, 5, 13))
ssi.m(); // ok
>ssi.m : Symbol(I.m, Decl(spreadMethods.ts, 1, 24))
>ssi : Symbol(ssi, Decl(spreadMethods.ts, 11, 3))
>m : Symbol(I.m, Decl(spreadMethods.ts, 1, 24))
>ssi.m : Symbol(I.m, Decl(spreadMethods.ts, 6, 14))
>ssi : Symbol(ssi, Decl(spreadMethods.ts, 23, 3))
>m : Symbol(I.m, Decl(spreadMethods.ts, 6, 14))
let o = { p: 12, m() { } };
>o : Symbol(o, Decl(spreadMethods.ts, 16, 3))
>p : Symbol(p, Decl(spreadMethods.ts, 16, 9))
>m : Symbol(m, Decl(spreadMethods.ts, 16, 16))
ssi.g; // ok
>ssi.g : Symbol(g, Decl(spreadMethods.ts, 7, 14))
>ssi : Symbol(ssi, Decl(spreadMethods.ts, 23, 3))
>g : Symbol(g, Decl(spreadMethods.ts, 7, 14))
let o = { p: 12, m() { }, get g() { return 0; } };
>o : Symbol(o, Decl(spreadMethods.ts, 31, 3))
>p : Symbol(p, Decl(spreadMethods.ts, 31, 9))
>m : Symbol(m, Decl(spreadMethods.ts, 31, 16))
>g : Symbol(g, Decl(spreadMethods.ts, 31, 25))
let so = { ...o };
>so : Symbol(so, Decl(spreadMethods.ts, 17, 3))
>o : Symbol(o, Decl(spreadMethods.ts, 16, 3))
>so : Symbol(so, Decl(spreadMethods.ts, 32, 3))
>o : Symbol(o, Decl(spreadMethods.ts, 31, 3))
let sso = { ...o, ...o };
>sso : Symbol(sso, Decl(spreadMethods.ts, 18, 3))
>o : Symbol(o, Decl(spreadMethods.ts, 16, 3))
>o : Symbol(o, Decl(spreadMethods.ts, 16, 3))
>sso : Symbol(sso, Decl(spreadMethods.ts, 33, 3))
>o : Symbol(o, Decl(spreadMethods.ts, 31, 3))
>o : Symbol(o, Decl(spreadMethods.ts, 31, 3))
so.p;
>so.p : Symbol(p, Decl(spreadMethods.ts, 16, 9))
>so : Symbol(so, Decl(spreadMethods.ts, 17, 3))
>p : Symbol(p, Decl(spreadMethods.ts, 16, 9))
>so.p : Symbol(p, Decl(spreadMethods.ts, 31, 9))
>so : Symbol(so, Decl(spreadMethods.ts, 32, 3))
>p : Symbol(p, Decl(spreadMethods.ts, 31, 9))
so.m(); // ok
>so.m : Symbol(m, Decl(spreadMethods.ts, 16, 16))
>so : Symbol(so, Decl(spreadMethods.ts, 17, 3))
>m : Symbol(m, Decl(spreadMethods.ts, 16, 16))
>so.m : Symbol(m, Decl(spreadMethods.ts, 31, 16))
>so : Symbol(so, Decl(spreadMethods.ts, 32, 3))
>m : Symbol(m, Decl(spreadMethods.ts, 31, 16))
so.g; // ok
>so.g : Symbol(g, Decl(spreadMethods.ts, 31, 25))
>so : Symbol(so, Decl(spreadMethods.ts, 32, 3))
>g : Symbol(g, Decl(spreadMethods.ts, 31, 25))
sso.p;
>sso.p : Symbol(p, Decl(spreadMethods.ts, 16, 9))
>sso : Symbol(sso, Decl(spreadMethods.ts, 18, 3))
>p : Symbol(p, Decl(spreadMethods.ts, 16, 9))
>sso.p : Symbol(p, Decl(spreadMethods.ts, 31, 9))
>sso : Symbol(sso, Decl(spreadMethods.ts, 33, 3))
>p : Symbol(p, Decl(spreadMethods.ts, 31, 9))
sso.m(); // ok
>sso.m : Symbol(m, Decl(spreadMethods.ts, 16, 16))
>sso : Symbol(sso, Decl(spreadMethods.ts, 18, 3))
>m : Symbol(m, Decl(spreadMethods.ts, 16, 16))
>sso.m : Symbol(m, Decl(spreadMethods.ts, 31, 16))
>sso : Symbol(sso, Decl(spreadMethods.ts, 33, 3))
>m : Symbol(m, Decl(spreadMethods.ts, 31, 16))
sso.g; // ok
>sso.g : Symbol(g, Decl(spreadMethods.ts, 31, 25))
>sso : Symbol(sso, Decl(spreadMethods.ts, 33, 3))
>g : Symbol(g, Decl(spreadMethods.ts, 31, 25))

View File

@@ -1,14 +1,29 @@
=== tests/cases/conformance/types/spread/spreadMethods.ts ===
class K { p = 12; m() { } }
class K {
>K : K
p = 12;
>p : number
>12 : 12
m() { }
>m : () => void
interface I { p: number, m(): void }
get g() { return 0; }
>g : number
>0 : 0
}
interface I {
p: number;
>p : number
m(): void;
>m : () => void
readonly g: number;
>g : number
}
let k = new K()
>k : K
>new K() : K
@@ -36,6 +51,11 @@ sk.m(); // error
>sk : { p: number; }
>m : any
sk.g; // error
>sk.g : any
>sk : { p: number; }
>g : any
ssk.p;
>ssk.p : number
>ssk : { p: number; }
@@ -47,83 +67,112 @@ ssk.m(); // error
>ssk : { p: number; }
>m : any
let i: I = { p: 12, m() { } };
ssk.g; // error
>ssk.g : any
>ssk : { p: number; }
>g : any
let i: I = { p: 12, m() { }, get g() { return 0; } };
>i : I
>{ p: 12, m() { } } : { p: number; m(): void; }
>{ p: 12, m() { }, get g() { return 0; } } : { p: number; m(): void; readonly g: number; }
>p : number
>12 : 12
>m : () => void
>g : number
>0 : 0
let si = { ...i };
>si : { p: number; m(): void; }
>{ ...i } : { p: number; m(): void; }
>si : { p: number; m(): void; g: number; }
>{ ...i } : { p: number; m(): void; g: number; }
>i : I
let ssi = { ...i, ...i };
>ssi : { p: number; m(): void; }
>{ ...i, ...i } : { p: number; m(): void; }
>ssi : { p: number; m(): void; g: number; }
>{ ...i, ...i } : { p: number; m(): void; g: number; }
>i : I
>i : I
si.p;
>si.p : number
>si : { p: number; m(): void; }
>si : { p: number; m(): void; g: number; }
>p : number
si.m(); // ok
>si.m() : void
>si.m : () => void
>si : { p: number; m(): void; }
>si : { p: number; m(): void; g: number; }
>m : () => void
si.g; // ok
>si.g : number
>si : { p: number; m(): void; g: number; }
>g : number
ssi.p;
>ssi.p : number
>ssi : { p: number; m(): void; }
>ssi : { p: number; m(): void; g: number; }
>p : number
ssi.m(); // ok
>ssi.m() : void
>ssi.m : () => void
>ssi : { p: number; m(): void; }
>ssi : { p: number; m(): void; g: number; }
>m : () => void
let o = { p: 12, m() { } };
>o : { p: number; m(): void; }
>{ p: 12, m() { } } : { p: number; m(): void; }
ssi.g; // ok
>ssi.g : number
>ssi : { p: number; m(): void; g: number; }
>g : number
let o = { p: 12, m() { }, get g() { return 0; } };
>o : { p: number; m(): void; readonly g: number; }
>{ p: 12, m() { }, get g() { return 0; } } : { p: number; m(): void; readonly g: number; }
>p : number
>12 : 12
>m : () => void
>g : number
>0 : 0
let so = { ...o };
>so : { p: number; m(): void; }
>{ ...o } : { p: number; m(): void; }
>o : { p: number; m(): void; }
>so : { p: number; m(): void; g: number; }
>{ ...o } : { p: number; m(): void; g: number; }
>o : { p: number; m(): void; readonly g: number; }
let sso = { ...o, ...o };
>sso : { p: number; m(): void; }
>{ ...o, ...o } : { p: number; m(): void; }
>o : { p: number; m(): void; }
>o : { p: number; m(): void; }
>sso : { p: number; m(): void; g: number; }
>{ ...o, ...o } : { p: number; m(): void; g: number; }
>o : { p: number; m(): void; readonly g: number; }
>o : { p: number; m(): void; readonly g: number; }
so.p;
>so.p : number
>so : { p: number; m(): void; }
>so : { p: number; m(): void; g: number; }
>p : number
so.m(); // ok
>so.m() : void
>so.m : () => void
>so : { p: number; m(): void; }
>so : { p: number; m(): void; g: number; }
>m : () => void
so.g; // ok
>so.g : number
>so : { p: number; m(): void; g: number; }
>g : number
sso.p;
>sso.p : number
>sso : { p: number; m(): void; }
>sso : { p: number; m(): void; g: number; }
>p : number
sso.m(); // ok
>sso.m() : void
>sso.m : () => void
>sso : { p: number; m(): void; }
>sso : { p: number; m(): void; g: number; }
>m : () => void
sso.g; // ok
>sso.g : number
>sso : { p: number; m(): void; g: number; }
>g : number

View File

@@ -1,23 +1,42 @@
class K { p = 12; m() { } }
interface I { p: number, m(): void }
// @target: esnext
class K {
p = 12;
m() { }
get g() { return 0; }
}
interface I {
p: number;
m(): void;
readonly g: number;
}
let k = new K()
let sk = { ...k };
let ssk = { ...k, ...k };
sk.p;
sk.m(); // error
sk.g; // error
ssk.p;
ssk.m(); // error
let i: I = { p: 12, m() { } };
ssk.g; // error
let i: I = { p: 12, m() { }, get g() { return 0; } };
let si = { ...i };
let ssi = { ...i, ...i };
si.p;
si.m(); // ok
si.g; // ok
ssi.p;
ssi.m(); // ok
let o = { p: 12, m() { } };
ssi.g; // ok
let o = { p: 12, m() { }, get g() { return 0; } };
let so = { ...o };
let sso = { ...o, ...o };
so.p;
so.m(); // ok
so.g; // ok
sso.p;
sso.m(); // ok
sso.g; // ok