Skip to content

Commit b45df89

Browse files
ajafffRyanCavanaugh
authored andcommitted
emit error on destructuring of rest property (#29609)
Fixes: #26005
1 parent dc7c9ba commit b45df89

File tree

6 files changed

+97
-0
lines changed

6 files changed

+97
-0
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31186,6 +31186,13 @@ namespace ts {
3118631186

3118731187
for (const prop of node.properties) {
3118831188
if (prop.kind === SyntaxKind.SpreadAssignment) {
31189+
if (inDestructuring) {
31190+
// a rest property cannot be destructured any further
31191+
const expression = skipParentheses(prop.expression);
31192+
if (isArrayLiteralExpression(expression) || isObjectLiteralExpression(expression)) {
31193+
return grammarErrorOnNode(prop.expression, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
31194+
}
31195+
}
3118931196
continue;
3119031197
}
3119131198
const name = prop.name;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(1,6): error TS2501: A rest element cannot contain a binding pattern.
2+
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(2,6): error TS2501: A rest element cannot contain a binding pattern.
3+
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(2,6): error TS2701: The target of an object rest assignment must be a variable or a property access.
4+
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(3,6): error TS2461: Type '{}' is not an array type.
5+
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(3,6): error TS2501: A rest element cannot contain a binding pattern.
6+
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(4,6): error TS2501: A rest element cannot contain a binding pattern.
7+
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(4,6): error TS2701: The target of an object rest assignment must be a variable or a property access.
8+
9+
10+
==== tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts (7 errors) ====
11+
({...{}} = {});
12+
~~
13+
!!! error TS2501: A rest element cannot contain a binding pattern.
14+
({...({})} = {});
15+
~~~~
16+
!!! error TS2501: A rest element cannot contain a binding pattern.
17+
~~~~
18+
!!! error TS2701: The target of an object rest assignment must be a variable or a property access.
19+
({...[]} = {});
20+
~~
21+
!!! error TS2461: Type '{}' is not an array type.
22+
~~
23+
!!! error TS2501: A rest element cannot contain a binding pattern.
24+
({...([])} = {});
25+
~~~~
26+
!!! error TS2501: A rest element cannot contain a binding pattern.
27+
~~~~
28+
!!! error TS2701: The target of an object rest assignment must be a variable or a property access.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//// [restPropertyWithBindingPattern.ts]
2+
({...{}} = {});
3+
({...({})} = {});
4+
({...[]} = {});
5+
({...([])} = {});
6+
7+
//// [restPropertyWithBindingPattern.js]
8+
var __rest = (this && this.__rest) || function (s, e) {
9+
var t = {};
10+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
11+
t[p] = s[p];
12+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
13+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0)
14+
t[p[i]] = s[p[i]];
15+
return t;
16+
};
17+
var _a, _b;
18+
(_a = __rest({}, []));
19+
(({}) = __rest({}, []));
20+
(_b = __rest({}, []));
21+
(([]) = __rest({}, []));
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
=== tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts ===
2+
({...{}} = {});
3+
No type information for this code.({...({})} = {});
4+
No type information for this code.({...[]} = {});
5+
No type information for this code.({...([])} = {});
6+
No type information for this code.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
=== tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts ===
2+
({...{}} = {});
3+
>({...{}} = {}) : {}
4+
>{...{}} = {} : {}
5+
>{...{}} : {}
6+
>{} : {}
7+
>{} : {}
8+
9+
({...({})} = {});
10+
>({...({})} = {}) : {}
11+
>{...({})} = {} : {}
12+
>{...({})} : {}
13+
>({}) : {}
14+
>{} : {}
15+
>{} : {}
16+
17+
({...[]} = {});
18+
>({...[]} = {}) : {}
19+
>{...[]} = {} : {}
20+
>{...[]} : { [n: number]: undefined; length: number; toString(): string; toLocaleString(): string; pop(): undefined; push(...items: undefined[]): number; concat(...items: ConcatArray<undefined>[]): undefined[]; concat(...items: ConcatArray<undefined>[]): undefined[]; join(separator?: string): string; reverse(): undefined[]; shift(): undefined; slice(start?: number, end?: number): undefined[]; sort(compareFn?: (a: undefined, b: undefined) => number): undefined[]; splice(start: number, deleteCount?: number): undefined[]; splice(start: number, deleteCount: number, ...items: undefined[]): undefined[]; unshift(...items: undefined[]): number; indexOf(searchElement: undefined, fromIndex?: number): number; lastIndexOf(searchElement: undefined, fromIndex?: number): number; every(callbackfn: (value: undefined, index: number, array: undefined[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: undefined, index: number, array: undefined[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: undefined, index: number, array: undefined[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: undefined, index: number, array: undefined[]) => U, thisArg?: any): U[]; filter<S extends undefined>(callbackfn: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: undefined, index: number, array: undefined[]) => any, thisArg?: any): undefined[]; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduce<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduceRight<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; }
21+
>[] : undefined[]
22+
>{} : {}
23+
24+
({...([])} = {});
25+
>({...([])} = {}) : {}
26+
>{...([])} = {} : {}
27+
>{...([])} : { [n: number]: undefined; length: number; toString(): string; toLocaleString(): string; pop(): undefined; push(...items: undefined[]): number; concat(...items: ConcatArray<undefined>[]): undefined[]; concat(...items: ConcatArray<undefined>[]): undefined[]; join(separator?: string): string; reverse(): undefined[]; shift(): undefined; slice(start?: number, end?: number): undefined[]; sort(compareFn?: (a: undefined, b: undefined) => number): undefined[]; splice(start: number, deleteCount?: number): undefined[]; splice(start: number, deleteCount: number, ...items: undefined[]): undefined[]; unshift(...items: undefined[]): number; indexOf(searchElement: undefined, fromIndex?: number): number; lastIndexOf(searchElement: undefined, fromIndex?: number): number; every(callbackfn: (value: undefined, index: number, array: undefined[]) => boolean, thisArg?: any): boolean; some(callbackfn: (value: undefined, index: number, array: undefined[]) => boolean, thisArg?: any): boolean; forEach(callbackfn: (value: undefined, index: number, array: undefined[]) => void, thisArg?: any): void; map<U>(callbackfn: (value: undefined, index: number, array: undefined[]) => U, thisArg?: any): U[]; filter<S extends undefined>(callbackfn: (value: undefined, index: number, array: undefined[]) => value is S, thisArg?: any): S[]; filter(callbackfn: (value: undefined, index: number, array: undefined[]) => any, thisArg?: any): undefined[]; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduce(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduce<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined): undefined; reduceRight(callbackfn: (previousValue: undefined, currentValue: undefined, currentIndex: number, array: undefined[]) => undefined, initialValue: undefined): undefined; reduceRight<U>(callbackfn: (previousValue: U, currentValue: undefined, currentIndex: number, array: undefined[]) => U, initialValue: U): U; }
28+
>([]) : undefined[]
29+
>[] : undefined[]
30+
>{} : {}
31+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
({...{}} = {});
2+
({...({})} = {});
3+
({...[]} = {});
4+
({...([])} = {});

0 commit comments

Comments
 (0)