Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
emit error on destructuring of rest property (#29609)
Fixes: #26005
  • Loading branch information
ajafff authored and RyanCavanaugh committed Apr 25, 2019
1 parent dc7c9ba commit b45df89
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/compiler/checker.ts
Expand Up @@ -31186,6 +31186,13 @@ namespace ts {

for (const prop of node.properties) {
if (prop.kind === SyntaxKind.SpreadAssignment) {
if (inDestructuring) {
// a rest property cannot be destructured any further
const expression = skipParentheses(prop.expression);
if (isArrayLiteralExpression(expression) || isObjectLiteralExpression(expression)) {
return grammarErrorOnNode(prop.expression, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
}
}
continue;
}
const name = prop.name;
Expand Down
@@ -0,0 +1,28 @@
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(1,6): error TS2501: A rest element cannot contain a binding pattern.
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(2,6): error TS2501: A rest element cannot contain a binding pattern.
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.
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(3,6): error TS2461: Type '{}' is not an array type.
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(3,6): error TS2501: A rest element cannot contain a binding pattern.
tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts(4,6): error TS2501: A rest element cannot contain a binding pattern.
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.


==== tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts (7 errors) ====
({...{}} = {});
~~
!!! error TS2501: A rest element cannot contain a binding pattern.
({...({})} = {});
~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
~~~~
!!! error TS2701: The target of an object rest assignment must be a variable or a property access.
({...[]} = {});
~~
!!! error TS2461: Type '{}' is not an array type.
~~
!!! error TS2501: A rest element cannot contain a binding pattern.
({...([])} = {});
~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
~~~~
!!! error TS2701: The target of an object rest assignment must be a variable or a property access.
21 changes: 21 additions & 0 deletions tests/baselines/reference/restPropertyWithBindingPattern.js
@@ -0,0 +1,21 @@
//// [restPropertyWithBindingPattern.ts]
({...{}} = {});
({...({})} = {});
({...[]} = {});
({...([])} = {});

//// [restPropertyWithBindingPattern.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)
t[p[i]] = s[p[i]];
return t;
};
var _a, _b;
(_a = __rest({}, []));
(({}) = __rest({}, []));
(_b = __rest({}, []));
(([]) = __rest({}, []));
@@ -0,0 +1,6 @@
=== tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts ===
({...{}} = {});
No type information for this code.({...({})} = {});
No type information for this code.({...[]} = {});
No type information for this code.({...([])} = {});
No type information for this code.
31 changes: 31 additions & 0 deletions tests/baselines/reference/restPropertyWithBindingPattern.types
@@ -0,0 +1,31 @@
=== tests/cases/conformance/es6/destructuring/restPropertyWithBindingPattern.ts ===
({...{}} = {});
>({...{}} = {}) : {}
>{...{}} = {} : {}
>{...{}} : {}
>{} : {}
>{} : {}

({...({})} = {});
>({...({})} = {}) : {}
>{...({})} = {} : {}
>{...({})} : {}
>({}) : {}
>{} : {}
>{} : {}

({...[]} = {});
>({...[]} = {}) : {}
>{...[]} = {} : {}
>{...[]} : { [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; }
>[] : undefined[]
>{} : {}

({...([])} = {});
>({...([])} = {}) : {}
>{...([])} = {} : {}
>{...([])} : { [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; }
>([]) : undefined[]
>[] : undefined[]
>{} : {}

@@ -0,0 +1,4 @@
({...{}} = {});
({...({})} = {});
({...[]} = {});
({...([])} = {});

0 comments on commit b45df89

Please sign in to comment.