diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 16644c2c5dc..7fa9406b907 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12906,8 +12906,9 @@ namespace ts { /** 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 | SymbolFlags.SetAccessor)) || - !prop.declarations.some(decl => isClassLike(decl.parent)); + return !some(prop.declarations, isPrivateIdentifierPropertyDeclaration) && + (!(prop.flags & (SymbolFlags.Method | SymbolFlags.GetAccessor | SymbolFlags.SetAccessor)) || + !prop.declarations.some(decl => isClassLike(decl.parent))); } function getSpreadSymbol(prop: Symbol, readonly: boolean) { diff --git a/tests/baselines/reference/privateNameAndObjectRestSpread.errors.txt b/tests/baselines/reference/privateNameAndObjectRestSpread.errors.txt new file mode 100644 index 00000000000..e55f40f3ba4 --- /dev/null +++ b/tests/baselines/reference/privateNameAndObjectRestSpread.errors.txt @@ -0,0 +1,19 @@ +tests/cases/conformance/classes/members/privateNames/privateNameAndObjectRestSpread.ts(6,13): error TS2339: Property '#prop' does not exist on type '{}'. +tests/cases/conformance/classes/members/privateNames/privateNameAndObjectRestSpread.ts(8,14): error TS2339: Property '#prop' does not exist on type '{}'. + + +==== tests/cases/conformance/classes/members/privateNames/privateNameAndObjectRestSpread.ts (2 errors) ==== + class C { + #prop = 1; + + method(other: C) { + const obj = { ...other }; + obj.#prop; + ~~~~~ +!!! error TS2339: Property '#prop' does not exist on type '{}'. + const { ...rest } = other; + rest.#prop; + ~~~~~ +!!! error TS2339: Property '#prop' does not exist on type '{}'. + } + } \ No newline at end of file diff --git a/tests/baselines/reference/privateNameAndObjectRestSpread.js b/tests/baselines/reference/privateNameAndObjectRestSpread.js new file mode 100644 index 00000000000..98a109257ae --- /dev/null +++ b/tests/baselines/reference/privateNameAndObjectRestSpread.js @@ -0,0 +1,44 @@ +//// [privateNameAndObjectRestSpread.ts] +class C { + #prop = 1; + + method(other: C) { + const obj = { ...other }; + obj.#prop; + const { ...rest } = other; + rest.#prop; + } +} + +//// [privateNameAndObjectRestSpread.js] +"use strict"; +var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) { + if (!privateMap.has(receiver)) { + throw new TypeError("attempted to get private field on non-instance"); + } + return privateMap.get(receiver); +}; +var __rest = (this && this.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +}; +var _prop; +class C { + constructor() { + _prop.set(this, 1); + } + method(other) { + const obj = Object.assign({}, other); + __classPrivateFieldGet(obj, _prop); + const rest = __rest(other, []); + __classPrivateFieldGet(rest, _prop); + } +} +_prop = new WeakMap(); diff --git a/tests/baselines/reference/privateNameAndObjectRestSpread.symbols b/tests/baselines/reference/privateNameAndObjectRestSpread.symbols new file mode 100644 index 00000000000..b9b3ef5eed4 --- /dev/null +++ b/tests/baselines/reference/privateNameAndObjectRestSpread.symbols @@ -0,0 +1,27 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndObjectRestSpread.ts === +class C { +>C : Symbol(C, Decl(privateNameAndObjectRestSpread.ts, 0, 0)) + + #prop = 1; +>#prop : Symbol(C.#prop, Decl(privateNameAndObjectRestSpread.ts, 0, 9)) + + method(other: C) { +>method : Symbol(C.method, Decl(privateNameAndObjectRestSpread.ts, 1, 14)) +>other : Symbol(other, Decl(privateNameAndObjectRestSpread.ts, 3, 11)) +>C : Symbol(C, Decl(privateNameAndObjectRestSpread.ts, 0, 0)) + + const obj = { ...other }; +>obj : Symbol(obj, Decl(privateNameAndObjectRestSpread.ts, 4, 13)) +>other : Symbol(other, Decl(privateNameAndObjectRestSpread.ts, 3, 11)) + + obj.#prop; +>obj : Symbol(obj, Decl(privateNameAndObjectRestSpread.ts, 4, 13)) + + const { ...rest } = other; +>rest : Symbol(rest, Decl(privateNameAndObjectRestSpread.ts, 6, 15)) +>other : Symbol(other, Decl(privateNameAndObjectRestSpread.ts, 3, 11)) + + rest.#prop; +>rest : Symbol(rest, Decl(privateNameAndObjectRestSpread.ts, 6, 15)) + } +} diff --git a/tests/baselines/reference/privateNameAndObjectRestSpread.types b/tests/baselines/reference/privateNameAndObjectRestSpread.types new file mode 100644 index 00000000000..0bab5992fa6 --- /dev/null +++ b/tests/baselines/reference/privateNameAndObjectRestSpread.types @@ -0,0 +1,30 @@ +=== tests/cases/conformance/classes/members/privateNames/privateNameAndObjectRestSpread.ts === +class C { +>C : C + + #prop = 1; +>#prop : number +>1 : 1 + + method(other: C) { +>method : (other: C) => void +>other : C + + const obj = { ...other }; +>obj : {} +>{ ...other } : {} +>other : C + + obj.#prop; +>obj.#prop : any +>obj : {} + + const { ...rest } = other; +>rest : {} +>other : C + + rest.#prop; +>rest.#prop : any +>rest : {} + } +} diff --git a/tests/cases/conformance/classes/members/privateNames/privateNameAndObjectRestSpread.ts b/tests/cases/conformance/classes/members/privateNames/privateNameAndObjectRestSpread.ts new file mode 100644 index 00000000000..9fed89d6549 --- /dev/null +++ b/tests/cases/conformance/classes/members/privateNames/privateNameAndObjectRestSpread.ts @@ -0,0 +1,13 @@ +// @strict: true +// @target: es6 + +class C { + #prop = 1; + + method(other: C) { + const obj = { ...other }; + obj.#prop; + const { ...rest } = other; + rest.#prop; + } +} \ No newline at end of file