diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 56a36f658d719..da42eefed3d6d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -8464,8 +8464,32 @@ namespace ts { if (source.flags & TypeFlags.Union) { return mapType(source, t => getRestType(t, properties, symbol)); } - const omitKeyType = getUnionType(map(properties, getLiteralTypeFromPropertyName)); + + let omitKeyType = getUnionType(map(properties, getLiteralTypeFromPropertyName)); + + const spreadableProperties: Symbol[] = []; + const unspreadableToRestKeys: Type[] = []; + + for (const prop of getPropertiesOfType(source)) { + const literalTypeFromProperty = getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique); + if (!isTypeAssignableTo(literalTypeFromProperty, omitKeyType) + && !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected)) + && isSpreadableProperty(prop)) { + spreadableProperties.push(prop); + } + else { + unspreadableToRestKeys.push(literalTypeFromProperty); + } + } + if (isGenericObjectType(source) || isGenericIndexType(omitKeyType)) { + if (unspreadableToRestKeys.length) { + // If the type we're spreading from has properties that cannot + // be spread into the rest type (e.g. getters, methods), ensure + // they are explicitly omitted, as they would in the non-generic case. + omitKeyType = getUnionType([omitKeyType, ...unspreadableToRestKeys]); + } + if (omitKeyType.flags & TypeFlags.Never) { return source; } @@ -8477,12 +8501,8 @@ namespace ts { return getTypeAliasInstantiation(omitTypeAlias, [source, omitKeyType]); } const members = createSymbolTable(); - for (const prop of getPropertiesOfType(source)) { - if (!isTypeAssignableTo(getLiteralTypeFromProperty(prop, TypeFlags.StringOrNumberLiteralOrUnique), omitKeyType) - && !(getDeclarationModifierFlagsFromSymbol(prop) & (ModifierFlags.Private | ModifierFlags.Protected)) - && isSpreadableProperty(prop)) { - members.set(prop.escapedName, getSpreadSymbol(prop, /*readonly*/ false)); - } + for (const prop of spreadableProperties) { + members.set(prop.escapedName, getSpreadSymbol(prop, /*readonly*/ false)); } const result = createAnonymousType(symbol, members, emptyArray, emptyArray, getIndexInfosOfType(source)); result.objectFlags |= ObjectFlags.ObjectRestType; diff --git a/tests/baselines/reference/destructuringUnspreadableIntoRest.errors.txt b/tests/baselines/reference/destructuringUnspreadableIntoRest.errors.txt new file mode 100644 index 0000000000000..20bcc06382504 --- /dev/null +++ b/tests/baselines/reference/destructuringUnspreadableIntoRest.errors.txt @@ -0,0 +1,223 @@ +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(22,15): error TS2339: Property 'publicProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(23,15): error TS2339: Property 'publicProp' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(25,15): error TS2339: Property 'privateProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(26,15): error TS2339: Property 'privateProp' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(27,15): error TS2339: Property 'privateProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(28,15): error TS2339: Property 'privateProp' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(30,15): error TS2339: Property 'protectedProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(31,15): error TS2339: Property 'protectedProp' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(32,15): error TS2339: Property 'protectedProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(33,15): error TS2339: Property 'protectedProp' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(35,15): error TS2339: Property 'getter' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(36,15): error TS2339: Property 'getter' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(37,15): error TS2339: Property 'getter' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(38,15): error TS2339: Property 'getter' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(40,15): error TS2339: Property 'setter' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(41,15): error TS2339: Property 'setter' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(42,15): error TS2339: Property 'setter' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(43,15): error TS2339: Property 'setter' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(45,15): error TS2339: Property 'method' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(46,15): error TS2339: Property 'method' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(47,15): error TS2339: Property 'method' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(48,15): error TS2339: Property 'method' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(60,11): error TS2339: Property 'publicProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(61,11): error TS2339: Property 'publicProp' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(63,11): error TS2339: Property 'privateProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(64,11): error TS2339: Property 'privateProp' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(65,11): error TS2339: Property 'privateProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(66,11): error TS2339: Property 'privateProp' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(68,11): error TS2339: Property 'protectedProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(69,11): error TS2339: Property 'protectedProp' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(70,11): error TS2339: Property 'protectedProp' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(71,11): error TS2339: Property 'protectedProp' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(73,11): error TS2339: Property 'getter' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(74,11): error TS2339: Property 'getter' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(75,11): error TS2339: Property 'getter' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(76,11): error TS2339: Property 'getter' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(78,11): error TS2339: Property 'setter' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(79,11): error TS2339: Property 'setter' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(80,11): error TS2339: Property 'setter' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(81,11): error TS2339: Property 'setter' does not exist on type '{}'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(83,11): error TS2339: Property 'method' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(84,11): error TS2339: Property 'method' does not exist on type '{ publicProp: string; }'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(85,11): error TS2339: Property 'method' does not exist on type 'Omit'. +tests/cases/compiler/destructuringUnspreadableIntoRest.ts(86,11): error TS2339: Property 'method' does not exist on type '{}'. + + +==== tests/cases/compiler/destructuringUnspreadableIntoRest.ts (44 errors) ==== + class A { + constructor( + public publicProp: string, + private privateProp: string, + protected protectedProp: string, + ) {} + + get getter(): number { + return 1; + } + + set setter(_v: number) {} + + method() { + const { ...rest1 } = this; + const { ...rest2 } = this as A; + const { publicProp: _1, ...rest3 } = this; + const { publicProp: _2, ...rest4 } = this as A; + + rest1.publicProp; + rest2.publicProp; + rest3.publicProp; + ~~~~~~~~~~ +!!! error TS2339: Property 'publicProp' does not exist on type 'Omit'. + rest4.publicProp; + ~~~~~~~~~~ +!!! error TS2339: Property 'publicProp' does not exist on type '{}'. + + rest1.privateProp; + ~~~~~~~~~~~ +!!! error TS2339: Property 'privateProp' does not exist on type 'Omit'. + rest2.privateProp; + ~~~~~~~~~~~ +!!! error TS2339: Property 'privateProp' does not exist on type '{ publicProp: string; }'. + rest3.privateProp; + ~~~~~~~~~~~ +!!! error TS2339: Property 'privateProp' does not exist on type 'Omit'. + rest4.privateProp; + ~~~~~~~~~~~ +!!! error TS2339: Property 'privateProp' does not exist on type '{}'. + + rest1.protectedProp; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'protectedProp' does not exist on type 'Omit'. + rest2.protectedProp; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'protectedProp' does not exist on type '{ publicProp: string; }'. + rest3.protectedProp; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'protectedProp' does not exist on type 'Omit'. + rest4.protectedProp; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'protectedProp' does not exist on type '{}'. + + rest1.getter; + ~~~~~~ +!!! error TS2339: Property 'getter' does not exist on type 'Omit'. + rest2.getter; + ~~~~~~ +!!! error TS2339: Property 'getter' does not exist on type '{ publicProp: string; }'. + rest3.getter; + ~~~~~~ +!!! error TS2339: Property 'getter' does not exist on type 'Omit'. + rest4.getter; + ~~~~~~ +!!! error TS2339: Property 'getter' does not exist on type '{}'. + + rest1.setter; + ~~~~~~ +!!! error TS2339: Property 'setter' does not exist on type 'Omit'. + rest2.setter; + ~~~~~~ +!!! error TS2339: Property 'setter' does not exist on type '{ publicProp: string; }'. + rest3.setter; + ~~~~~~ +!!! error TS2339: Property 'setter' does not exist on type 'Omit'. + rest4.setter; + ~~~~~~ +!!! error TS2339: Property 'setter' does not exist on type '{}'. + + rest1.method; + ~~~~~~ +!!! error TS2339: Property 'method' does not exist on type 'Omit'. + rest2.method; + ~~~~~~ +!!! error TS2339: Property 'method' does not exist on type '{ publicProp: string; }'. + rest3.method; + ~~~~~~ +!!! error TS2339: Property 'method' does not exist on type 'Omit'. + rest4.method; + ~~~~~~ +!!! error TS2339: Property 'method' does not exist on type '{}'. + } + } + + function destructure(x: T) { + const { ...rest1 } = x; + const { ...rest2 } = x as A; + const { publicProp: _1, ...rest3 } = x; + const { publicProp: _2, ...rest4 } = x as A; + + rest1.publicProp; + rest2.publicProp; + rest3.publicProp; + ~~~~~~~~~~ +!!! error TS2339: Property 'publicProp' does not exist on type 'Omit'. + rest4.publicProp; + ~~~~~~~~~~ +!!! error TS2339: Property 'publicProp' does not exist on type '{}'. + + rest1.privateProp; + ~~~~~~~~~~~ +!!! error TS2339: Property 'privateProp' does not exist on type 'Omit'. + rest2.privateProp; + ~~~~~~~~~~~ +!!! error TS2339: Property 'privateProp' does not exist on type '{ publicProp: string; }'. + rest3.privateProp; + ~~~~~~~~~~~ +!!! error TS2339: Property 'privateProp' does not exist on type 'Omit'. + rest4.privateProp; + ~~~~~~~~~~~ +!!! error TS2339: Property 'privateProp' does not exist on type '{}'. + + rest1.protectedProp; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'protectedProp' does not exist on type 'Omit'. + rest2.protectedProp; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'protectedProp' does not exist on type '{ publicProp: string; }'. + rest3.protectedProp; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'protectedProp' does not exist on type 'Omit'. + rest4.protectedProp; + ~~~~~~~~~~~~~ +!!! error TS2339: Property 'protectedProp' does not exist on type '{}'. + + rest1.getter; + ~~~~~~ +!!! error TS2339: Property 'getter' does not exist on type 'Omit'. + rest2.getter; + ~~~~~~ +!!! error TS2339: Property 'getter' does not exist on type '{ publicProp: string; }'. + rest3.getter; + ~~~~~~ +!!! error TS2339: Property 'getter' does not exist on type 'Omit'. + rest4.getter; + ~~~~~~ +!!! error TS2339: Property 'getter' does not exist on type '{}'. + + rest1.setter; + ~~~~~~ +!!! error TS2339: Property 'setter' does not exist on type 'Omit'. + rest2.setter; + ~~~~~~ +!!! error TS2339: Property 'setter' does not exist on type '{ publicProp: string; }'. + rest3.setter; + ~~~~~~ +!!! error TS2339: Property 'setter' does not exist on type 'Omit'. + rest4.setter; + ~~~~~~ +!!! error TS2339: Property 'setter' does not exist on type '{}'. + + rest1.method; + ~~~~~~ +!!! error TS2339: Property 'method' does not exist on type 'Omit'. + rest2.method; + ~~~~~~ +!!! error TS2339: Property 'method' does not exist on type '{ publicProp: string; }'. + rest3.method; + ~~~~~~ +!!! error TS2339: Property 'method' does not exist on type 'Omit'. + rest4.method; + ~~~~~~ +!!! error TS2339: Property 'method' does not exist on type '{}'. + } + \ No newline at end of file diff --git a/tests/baselines/reference/destructuringUnspreadableIntoRest.js b/tests/baselines/reference/destructuringUnspreadableIntoRest.js new file mode 100644 index 0000000000000..e4ee1a835cec4 --- /dev/null +++ b/tests/baselines/reference/destructuringUnspreadableIntoRest.js @@ -0,0 +1,173 @@ +//// [destructuringUnspreadableIntoRest.ts] +class A { + constructor( + public publicProp: string, + private privateProp: string, + protected protectedProp: string, + ) {} + + get getter(): number { + return 1; + } + + set setter(_v: number) {} + + method() { + const { ...rest1 } = this; + const { ...rest2 } = this as A; + const { publicProp: _1, ...rest3 } = this; + const { publicProp: _2, ...rest4 } = this as A; + + rest1.publicProp; + rest2.publicProp; + rest3.publicProp; + rest4.publicProp; + + rest1.privateProp; + rest2.privateProp; + rest3.privateProp; + rest4.privateProp; + + rest1.protectedProp; + rest2.protectedProp; + rest3.protectedProp; + rest4.protectedProp; + + rest1.getter; + rest2.getter; + rest3.getter; + rest4.getter; + + rest1.setter; + rest2.setter; + rest3.setter; + rest4.setter; + + rest1.method; + rest2.method; + rest3.method; + rest4.method; + } +} + +function destructure(x: T) { + const { ...rest1 } = x; + const { ...rest2 } = x as A; + const { publicProp: _1, ...rest3 } = x; + const { publicProp: _2, ...rest4 } = x as A; + + rest1.publicProp; + rest2.publicProp; + rest3.publicProp; + rest4.publicProp; + + rest1.privateProp; + rest2.privateProp; + rest3.privateProp; + rest4.privateProp; + + rest1.protectedProp; + rest2.protectedProp; + rest3.protectedProp; + rest4.protectedProp; + + rest1.getter; + rest2.getter; + rest3.getter; + rest4.getter; + + rest1.setter; + rest2.setter; + rest3.setter; + rest4.setter; + + rest1.method; + rest2.method; + rest3.method; + rest4.method; +} + + +//// [destructuringUnspreadableIntoRest.js] +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; +}; +class A { + constructor(publicProp, privateProp, protectedProp) { + this.publicProp = publicProp; + this.privateProp = privateProp; + this.protectedProp = protectedProp; + } + get getter() { + return 1; + } + set setter(_v) { } + method() { + const rest1 = __rest(this, []); + const rest2 = __rest(this, []); + const _a = this, { publicProp: _1 } = _a, rest3 = __rest(_a, ["publicProp"]); + const _b = this, { publicProp: _2 } = _b, rest4 = __rest(_b, ["publicProp"]); + rest1.publicProp; + rest2.publicProp; + rest3.publicProp; + rest4.publicProp; + rest1.privateProp; + rest2.privateProp; + rest3.privateProp; + rest4.privateProp; + rest1.protectedProp; + rest2.protectedProp; + rest3.protectedProp; + rest4.protectedProp; + rest1.getter; + rest2.getter; + rest3.getter; + rest4.getter; + rest1.setter; + rest2.setter; + rest3.setter; + rest4.setter; + rest1.method; + rest2.method; + rest3.method; + rest4.method; + } +} +function destructure(x) { + const rest1 = __rest(x, []); + const rest2 = __rest(x, []); + const { publicProp: _1 } = x, rest3 = __rest(x, ["publicProp"]); + const _a = x, { publicProp: _2 } = _a, rest4 = __rest(_a, ["publicProp"]); + rest1.publicProp; + rest2.publicProp; + rest3.publicProp; + rest4.publicProp; + rest1.privateProp; + rest2.privateProp; + rest3.privateProp; + rest4.privateProp; + rest1.protectedProp; + rest2.protectedProp; + rest3.protectedProp; + rest4.protectedProp; + rest1.getter; + rest2.getter; + rest3.getter; + rest4.getter; + rest1.setter; + rest2.setter; + rest3.setter; + rest4.setter; + rest1.method; + rest2.method; + rest3.method; + rest4.method; +} diff --git a/tests/baselines/reference/destructuringUnspreadableIntoRest.symbols b/tests/baselines/reference/destructuringUnspreadableIntoRest.symbols new file mode 100644 index 0000000000000..557afeeffa912 --- /dev/null +++ b/tests/baselines/reference/destructuringUnspreadableIntoRest.symbols @@ -0,0 +1,235 @@ +=== tests/cases/compiler/destructuringUnspreadableIntoRest.ts === +class A { +>A : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) + + constructor( + public publicProp: string, +>publicProp : Symbol(A.publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) + + private privateProp: string, +>privateProp : Symbol(A.privateProp, Decl(destructuringUnspreadableIntoRest.ts, 2, 34)) + + protected protectedProp: string, +>protectedProp : Symbol(A.protectedProp, Decl(destructuringUnspreadableIntoRest.ts, 3, 36)) + + ) {} + + get getter(): number { +>getter : Symbol(A.getter, Decl(destructuringUnspreadableIntoRest.ts, 5, 8)) + + return 1; + } + + set setter(_v: number) {} +>setter : Symbol(A.setter, Decl(destructuringUnspreadableIntoRest.ts, 9, 5)) +>_v : Symbol(_v, Decl(destructuringUnspreadableIntoRest.ts, 11, 15)) + + method() { +>method : Symbol(A.method, Decl(destructuringUnspreadableIntoRest.ts, 11, 29)) + + const { ...rest1 } = this; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 14, 15)) +>this : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) + + const { ...rest2 } = this as A; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 15, 15)) +>this : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) +>A : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) + + const { publicProp: _1, ...rest3 } = this; +>publicProp : Symbol(A.publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) +>_1 : Symbol(_1, Decl(destructuringUnspreadableIntoRest.ts, 16, 15)) +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 16, 31)) +>this : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) + + const { publicProp: _2, ...rest4 } = this as A; +>publicProp : Symbol(A.publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) +>_2 : Symbol(_2, Decl(destructuringUnspreadableIntoRest.ts, 17, 15)) +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 17, 31)) +>this : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) +>A : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) + + rest1.publicProp; +>rest1.publicProp : Symbol(publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 14, 15)) +>publicProp : Symbol(publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) + + rest2.publicProp; +>rest2.publicProp : Symbol(A.publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 15, 15)) +>publicProp : Symbol(A.publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) + + rest3.publicProp; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 16, 31)) + + rest4.publicProp; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 17, 31)) + + rest1.privateProp; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 14, 15)) + + rest2.privateProp; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 15, 15)) + + rest3.privateProp; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 16, 31)) + + rest4.privateProp; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 17, 31)) + + rest1.protectedProp; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 14, 15)) + + rest2.protectedProp; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 15, 15)) + + rest3.protectedProp; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 16, 31)) + + rest4.protectedProp; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 17, 31)) + + rest1.getter; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 14, 15)) + + rest2.getter; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 15, 15)) + + rest3.getter; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 16, 31)) + + rest4.getter; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 17, 31)) + + rest1.setter; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 14, 15)) + + rest2.setter; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 15, 15)) + + rest3.setter; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 16, 31)) + + rest4.setter; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 17, 31)) + + rest1.method; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 14, 15)) + + rest2.method; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 15, 15)) + + rest3.method; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 16, 31)) + + rest4.method; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 17, 31)) + } +} + +function destructure(x: T) { +>destructure : Symbol(destructure, Decl(destructuringUnspreadableIntoRest.ts, 49, 1)) +>T : Symbol(T, Decl(destructuringUnspreadableIntoRest.ts, 51, 21)) +>A : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) +>x : Symbol(x, Decl(destructuringUnspreadableIntoRest.ts, 51, 34)) +>T : Symbol(T, Decl(destructuringUnspreadableIntoRest.ts, 51, 21)) + + const { ...rest1 } = x; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 52, 11)) +>x : Symbol(x, Decl(destructuringUnspreadableIntoRest.ts, 51, 34)) + + const { ...rest2 } = x as A; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 53, 11)) +>x : Symbol(x, Decl(destructuringUnspreadableIntoRest.ts, 51, 34)) +>A : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) + + const { publicProp: _1, ...rest3 } = x; +>publicProp : Symbol(A.publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) +>_1 : Symbol(_1, Decl(destructuringUnspreadableIntoRest.ts, 54, 11)) +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 54, 27)) +>x : Symbol(x, Decl(destructuringUnspreadableIntoRest.ts, 51, 34)) + + const { publicProp: _2, ...rest4 } = x as A; +>publicProp : Symbol(A.publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) +>_2 : Symbol(_2, Decl(destructuringUnspreadableIntoRest.ts, 55, 11)) +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 55, 27)) +>x : Symbol(x, Decl(destructuringUnspreadableIntoRest.ts, 51, 34)) +>A : Symbol(A, Decl(destructuringUnspreadableIntoRest.ts, 0, 0)) + + rest1.publicProp; +>rest1.publicProp : Symbol(publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 52, 11)) +>publicProp : Symbol(publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) + + rest2.publicProp; +>rest2.publicProp : Symbol(A.publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 53, 11)) +>publicProp : Symbol(A.publicProp, Decl(destructuringUnspreadableIntoRest.ts, 1, 16)) + + rest3.publicProp; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 54, 27)) + + rest4.publicProp; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 55, 27)) + + rest1.privateProp; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 52, 11)) + + rest2.privateProp; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 53, 11)) + + rest3.privateProp; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 54, 27)) + + rest4.privateProp; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 55, 27)) + + rest1.protectedProp; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 52, 11)) + + rest2.protectedProp; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 53, 11)) + + rest3.protectedProp; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 54, 27)) + + rest4.protectedProp; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 55, 27)) + + rest1.getter; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 52, 11)) + + rest2.getter; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 53, 11)) + + rest3.getter; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 54, 27)) + + rest4.getter; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 55, 27)) + + rest1.setter; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 52, 11)) + + rest2.setter; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 53, 11)) + + rest3.setter; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 54, 27)) + + rest4.setter; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 55, 27)) + + rest1.method; +>rest1 : Symbol(rest1, Decl(destructuringUnspreadableIntoRest.ts, 52, 11)) + + rest2.method; +>rest2 : Symbol(rest2, Decl(destructuringUnspreadableIntoRest.ts, 53, 11)) + + rest3.method; +>rest3 : Symbol(rest3, Decl(destructuringUnspreadableIntoRest.ts, 54, 27)) + + rest4.method; +>rest4 : Symbol(rest4, Decl(destructuringUnspreadableIntoRest.ts, 55, 27)) +} + diff --git a/tests/baselines/reference/destructuringUnspreadableIntoRest.types b/tests/baselines/reference/destructuringUnspreadableIntoRest.types new file mode 100644 index 0000000000000..5fefa899662b3 --- /dev/null +++ b/tests/baselines/reference/destructuringUnspreadableIntoRest.types @@ -0,0 +1,321 @@ +=== tests/cases/compiler/destructuringUnspreadableIntoRest.ts === +class A { +>A : A + + constructor( + public publicProp: string, +>publicProp : string + + private privateProp: string, +>privateProp : string + + protected protectedProp: string, +>protectedProp : string + + ) {} + + get getter(): number { +>getter : number + + return 1; +>1 : 1 + } + + set setter(_v: number) {} +>setter : number +>_v : number + + method() { +>method : () => void + + const { ...rest1 } = this; +>rest1 : Omit +>this : this + + const { ...rest2 } = this as A; +>rest2 : { publicProp: string; } +>this as A : A +>this : this + + const { publicProp: _1, ...rest3 } = this; +>publicProp : any +>_1 : string +>rest3 : Omit +>this : this + + const { publicProp: _2, ...rest4 } = this as A; +>publicProp : any +>_2 : string +>rest4 : {} +>this as A : A +>this : this + + rest1.publicProp; +>rest1.publicProp : this["publicProp"] +>rest1 : Omit +>publicProp : this["publicProp"] + + rest2.publicProp; +>rest2.publicProp : string +>rest2 : { publicProp: string; } +>publicProp : string + + rest3.publicProp; +>rest3.publicProp : any +>rest3 : Omit +>publicProp : any + + rest4.publicProp; +>rest4.publicProp : any +>rest4 : {} +>publicProp : any + + rest1.privateProp; +>rest1.privateProp : any +>rest1 : Omit +>privateProp : any + + rest2.privateProp; +>rest2.privateProp : any +>rest2 : { publicProp: string; } +>privateProp : any + + rest3.privateProp; +>rest3.privateProp : any +>rest3 : Omit +>privateProp : any + + rest4.privateProp; +>rest4.privateProp : any +>rest4 : {} +>privateProp : any + + rest1.protectedProp; +>rest1.protectedProp : any +>rest1 : Omit +>protectedProp : any + + rest2.protectedProp; +>rest2.protectedProp : any +>rest2 : { publicProp: string; } +>protectedProp : any + + rest3.protectedProp; +>rest3.protectedProp : any +>rest3 : Omit +>protectedProp : any + + rest4.protectedProp; +>rest4.protectedProp : any +>rest4 : {} +>protectedProp : any + + rest1.getter; +>rest1.getter : any +>rest1 : Omit +>getter : any + + rest2.getter; +>rest2.getter : any +>rest2 : { publicProp: string; } +>getter : any + + rest3.getter; +>rest3.getter : any +>rest3 : Omit +>getter : any + + rest4.getter; +>rest4.getter : any +>rest4 : {} +>getter : any + + rest1.setter; +>rest1.setter : any +>rest1 : Omit +>setter : any + + rest2.setter; +>rest2.setter : any +>rest2 : { publicProp: string; } +>setter : any + + rest3.setter; +>rest3.setter : any +>rest3 : Omit +>setter : any + + rest4.setter; +>rest4.setter : any +>rest4 : {} +>setter : any + + rest1.method; +>rest1.method : any +>rest1 : Omit +>method : any + + rest2.method; +>rest2.method : any +>rest2 : { publicProp: string; } +>method : any + + rest3.method; +>rest3.method : any +>rest3 : Omit +>method : any + + rest4.method; +>rest4.method : any +>rest4 : {} +>method : any + } +} + +function destructure(x: T) { +>destructure : (x: T) => void +>x : T + + const { ...rest1 } = x; +>rest1 : Omit +>x : T + + const { ...rest2 } = x as A; +>rest2 : { publicProp: string; } +>x as A : A +>x : T + + const { publicProp: _1, ...rest3 } = x; +>publicProp : any +>_1 : string +>rest3 : Omit +>x : T + + const { publicProp: _2, ...rest4 } = x as A; +>publicProp : any +>_2 : string +>rest4 : {} +>x as A : A +>x : T + + rest1.publicProp; +>rest1.publicProp : T["publicProp"] +>rest1 : Omit +>publicProp : T["publicProp"] + + rest2.publicProp; +>rest2.publicProp : string +>rest2 : { publicProp: string; } +>publicProp : string + + rest3.publicProp; +>rest3.publicProp : any +>rest3 : Omit +>publicProp : any + + rest4.publicProp; +>rest4.publicProp : any +>rest4 : {} +>publicProp : any + + rest1.privateProp; +>rest1.privateProp : any +>rest1 : Omit +>privateProp : any + + rest2.privateProp; +>rest2.privateProp : any +>rest2 : { publicProp: string; } +>privateProp : any + + rest3.privateProp; +>rest3.privateProp : any +>rest3 : Omit +>privateProp : any + + rest4.privateProp; +>rest4.privateProp : any +>rest4 : {} +>privateProp : any + + rest1.protectedProp; +>rest1.protectedProp : any +>rest1 : Omit +>protectedProp : any + + rest2.protectedProp; +>rest2.protectedProp : any +>rest2 : { publicProp: string; } +>protectedProp : any + + rest3.protectedProp; +>rest3.protectedProp : any +>rest3 : Omit +>protectedProp : any + + rest4.protectedProp; +>rest4.protectedProp : any +>rest4 : {} +>protectedProp : any + + rest1.getter; +>rest1.getter : any +>rest1 : Omit +>getter : any + + rest2.getter; +>rest2.getter : any +>rest2 : { publicProp: string; } +>getter : any + + rest3.getter; +>rest3.getter : any +>rest3 : Omit +>getter : any + + rest4.getter; +>rest4.getter : any +>rest4 : {} +>getter : any + + rest1.setter; +>rest1.setter : any +>rest1 : Omit +>setter : any + + rest2.setter; +>rest2.setter : any +>rest2 : { publicProp: string; } +>setter : any + + rest3.setter; +>rest3.setter : any +>rest3 : Omit +>setter : any + + rest4.setter; +>rest4.setter : any +>rest4 : {} +>setter : any + + rest1.method; +>rest1.method : any +>rest1 : Omit +>method : any + + rest2.method; +>rest2.method : any +>rest2 : { publicProp: string; } +>method : any + + rest3.method; +>rest3.method : any +>rest3 : Omit +>method : any + + rest4.method; +>rest4.method : any +>rest4 : {} +>method : any +} + diff --git a/tests/cases/compiler/destructuringUnspreadableIntoRest.ts b/tests/cases/compiler/destructuringUnspreadableIntoRest.ts new file mode 100644 index 0000000000000..11e0cc73dea4b --- /dev/null +++ b/tests/cases/compiler/destructuringUnspreadableIntoRest.ts @@ -0,0 +1,88 @@ +//@target: ES6 +class A { + constructor( + public publicProp: string, + private privateProp: string, + protected protectedProp: string, + ) {} + + get getter(): number { + return 1; + } + + set setter(_v: number) {} + + method() { + const { ...rest1 } = this; + const { ...rest2 } = this as A; + const { publicProp: _1, ...rest3 } = this; + const { publicProp: _2, ...rest4 } = this as A; + + rest1.publicProp; + rest2.publicProp; + rest3.publicProp; + rest4.publicProp; + + rest1.privateProp; + rest2.privateProp; + rest3.privateProp; + rest4.privateProp; + + rest1.protectedProp; + rest2.protectedProp; + rest3.protectedProp; + rest4.protectedProp; + + rest1.getter; + rest2.getter; + rest3.getter; + rest4.getter; + + rest1.setter; + rest2.setter; + rest3.setter; + rest4.setter; + + rest1.method; + rest2.method; + rest3.method; + rest4.method; + } +} + +function destructure(x: T) { + const { ...rest1 } = x; + const { ...rest2 } = x as A; + const { publicProp: _1, ...rest3 } = x; + const { publicProp: _2, ...rest4 } = x as A; + + rest1.publicProp; + rest2.publicProp; + rest3.publicProp; + rest4.publicProp; + + rest1.privateProp; + rest2.privateProp; + rest3.privateProp; + rest4.privateProp; + + rest1.protectedProp; + rest2.protectedProp; + rest3.protectedProp; + rest4.protectedProp; + + rest1.getter; + rest2.getter; + rest3.getter; + rest4.getter; + + rest1.setter; + rest2.setter; + rest3.setter; + rest4.setter; + + rest1.method; + rest2.method; + rest3.method; + rest4.method; +}