Disallow binding patterns in rest parameters

This commit is contained in:
Jason Freeman
2015-04-09 18:19:25 -07:00
parent 2d3b22cbba
commit e9f5acce75
15 changed files with 102 additions and 191 deletions

View File

@@ -12243,6 +12243,10 @@ module ts {
return grammarErrorOnNode(parameter.dotDotDotToken, Diagnostics.A_rest_parameter_must_be_last_in_a_parameter_list);
}
if (parameter.name.kind === SyntaxKind.ArrayBindingPattern || parameter.name.kind === SyntaxKind.ObjectBindingPattern) {
return grammarErrorOnNode(parameter.name, Diagnostics.A_rest_element_cannot_contain_a_binding_pattern);
}
if (parameter.questionToken) {
return grammarErrorOnNode(parameter.questionToken, Diagnostics.A_rest_parameter_cannot_be_optional);
}

View File

@@ -0,0 +1,22 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts(1,17): error TS2501: A rest element cannot contain a binding pattern.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts (1 errors) ====
function fun(...[a, ...b]) { }
~~~~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
fun(new FooIterator);
class Bar { x }
class Foo extends Bar { y }
class FooIterator {
next() {
return {
value: new Foo,
done: false
};
}
[Symbol.iterator]() {
return this;
}
}

View File

@@ -1,51 +0,0 @@
=== tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts ===
function fun(...[a, ...b]) { }
>fun : (...[a, ...b]: any[]) => void, Symbol(fun, Decl(iterableArrayPattern14.ts, 0, 0))
>a : any, Symbol(a, Decl(iterableArrayPattern14.ts, 0, 17))
>b : any[], Symbol(b, Decl(iterableArrayPattern14.ts, 0, 19))
fun(new FooIterator);
>fun(new FooIterator) : void
>fun : (...[a, ...b]: any[]) => void, Symbol(fun, Decl(iterableArrayPattern14.ts, 0, 0))
>new FooIterator : FooIterator
>FooIterator : typeof FooIterator, Symbol(FooIterator, Decl(iterableArrayPattern14.ts, 3, 27))
class Bar { x }
>Bar : Bar, Symbol(Bar, Decl(iterableArrayPattern14.ts, 1, 21))
>x : any, Symbol(x, Decl(iterableArrayPattern14.ts, 2, 11))
class Foo extends Bar { y }
>Foo : Foo, Symbol(Foo, Decl(iterableArrayPattern14.ts, 2, 15))
>Bar : Bar, Symbol(Bar, Decl(iterableArrayPattern14.ts, 1, 21))
>y : any, Symbol(y, Decl(iterableArrayPattern14.ts, 3, 23))
class FooIterator {
>FooIterator : FooIterator, Symbol(FooIterator, Decl(iterableArrayPattern14.ts, 3, 27))
next() {
>next : () => { value: Foo; done: boolean; }, Symbol(next, Decl(iterableArrayPattern14.ts, 4, 19))
return {
>{ value: new Foo, done: false } : { value: Foo; done: boolean; }
value: new Foo,
>value : Foo, Symbol(value, Decl(iterableArrayPattern14.ts, 6, 16))
>new Foo : Foo
>Foo : typeof Foo, Symbol(Foo, Decl(iterableArrayPattern14.ts, 2, 15))
done: false
>done : boolean, Symbol(done, Decl(iterableArrayPattern14.ts, 7, 27))
>false : boolean
};
}
[Symbol.iterator]() {
>Symbol.iterator : symbol, Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1236, 31))
>Symbol : SymbolConstructor, Symbol(Symbol, Decl(lib.d.ts, 1186, 52), Decl(lib.d.ts, 1262, 11))
>iterator : symbol, Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1236, 31))
return this;
>this : FooIterator, Symbol(FooIterator, Decl(iterableArrayPattern14.ts, 3, 27))
}
}

View File

@@ -0,0 +1,22 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts(1,17): error TS2501: A rest element cannot contain a binding pattern.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts (1 errors) ====
function fun(...[a, b]: Bar[]) { }
~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
fun(...new FooIterator);
class Bar { x }
class Foo extends Bar { y }
class FooIterator {
next() {
return {
value: new Foo,
done: false
};
}
[Symbol.iterator]() {
return this;
}
}

View File

@@ -1,53 +0,0 @@
=== tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts ===
function fun(...[a, b]: Bar[]) { }
>fun : (...[a, b]: Bar[]) => void, Symbol(fun, Decl(iterableArrayPattern15.ts, 0, 0))
>a : Bar, Symbol(a, Decl(iterableArrayPattern15.ts, 0, 17))
>b : Bar, Symbol(b, Decl(iterableArrayPattern15.ts, 0, 19))
>Bar : Bar, Symbol(Bar, Decl(iterableArrayPattern15.ts, 1, 24))
fun(...new FooIterator);
>fun(...new FooIterator) : void
>fun : (...[a, b]: Bar[]) => void, Symbol(fun, Decl(iterableArrayPattern15.ts, 0, 0))
>...new FooIterator : Foo
>new FooIterator : FooIterator
>FooIterator : typeof FooIterator, Symbol(FooIterator, Decl(iterableArrayPattern15.ts, 3, 27))
class Bar { x }
>Bar : Bar, Symbol(Bar, Decl(iterableArrayPattern15.ts, 1, 24))
>x : any, Symbol(x, Decl(iterableArrayPattern15.ts, 2, 11))
class Foo extends Bar { y }
>Foo : Foo, Symbol(Foo, Decl(iterableArrayPattern15.ts, 2, 15))
>Bar : Bar, Symbol(Bar, Decl(iterableArrayPattern15.ts, 1, 24))
>y : any, Symbol(y, Decl(iterableArrayPattern15.ts, 3, 23))
class FooIterator {
>FooIterator : FooIterator, Symbol(FooIterator, Decl(iterableArrayPattern15.ts, 3, 27))
next() {
>next : () => { value: Foo; done: boolean; }, Symbol(next, Decl(iterableArrayPattern15.ts, 4, 19))
return {
>{ value: new Foo, done: false } : { value: Foo; done: boolean; }
value: new Foo,
>value : Foo, Symbol(value, Decl(iterableArrayPattern15.ts, 6, 16))
>new Foo : Foo
>Foo : typeof Foo, Symbol(Foo, Decl(iterableArrayPattern15.ts, 2, 15))
done: false
>done : boolean, Symbol(done, Decl(iterableArrayPattern15.ts, 7, 27))
>false : boolean
};
}
[Symbol.iterator]() {
>Symbol.iterator : symbol, Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1236, 31))
>Symbol : SymbolConstructor, Symbol(Symbol, Decl(lib.d.ts, 1186, 52), Decl(lib.d.ts, 1262, 11))
>iterator : symbol, Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1236, 31))
return this;
>this : FooIterator, Symbol(FooIterator, Decl(iterableArrayPattern15.ts, 3, 27))
}
}

View File

@@ -1,9 +1,12 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(1,17): error TS2501: A rest element cannot contain a binding pattern.
tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts(2,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'.
Property '0' is missing in type 'FooIterator'.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts (1 errors) ====
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts (2 errors) ====
function fun(...[a, b]: [Bar, Bar][]) { }
~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
fun(...new FooIteratorIterator);
~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type '[Bar, Bar]'.

View File

@@ -1,9 +1,12 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(1,17): error TS2501: A rest element cannot contain a binding pattern.
tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(2,5): error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'.
Property 'x' is missing in type 'FooIterator'.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts (1 errors) ====
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts (2 errors) ====
function fun(...[a, b]: Bar[]) { }
~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
fun(new FooIterator);
~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type 'FooIterator' is not assignable to parameter of type 'Bar'.

View File

@@ -0,0 +1,22 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts(1,17): error TS2501: A rest element cannot contain a binding pattern.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts (1 errors) ====
function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
fun(...new FooArrayIterator);
class Bar { x }
class Foo extends Bar { y }
class FooArrayIterator {
next() {
return {
value: [new Foo],
done: false
};
}
[Symbol.iterator]() {
return this;
}
}

View File

@@ -1,59 +0,0 @@
=== tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts ===
function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { }
>fun : (...[[a = new Foo], b = [new Foo]]: Bar[][]) => void, Symbol(fun, Decl(iterableArrayPattern20.ts, 0, 0))
>a : Bar, Symbol(a, Decl(iterableArrayPattern20.ts, 0, 18))
>new Foo : Foo
>Foo : typeof Foo, Symbol(Foo, Decl(iterableArrayPattern20.ts, 2, 15))
>b : Bar[], Symbol(b, Decl(iterableArrayPattern20.ts, 0, 31))
>[new Foo] : Foo[]
>new Foo : Foo
>Foo : typeof Foo, Symbol(Foo, Decl(iterableArrayPattern20.ts, 2, 15))
>Bar : Bar, Symbol(Bar, Decl(iterableArrayPattern20.ts, 1, 29))
fun(...new FooArrayIterator);
>fun(...new FooArrayIterator) : void
>fun : (...[[a = new Foo], b = [new Foo]]: Bar[][]) => void, Symbol(fun, Decl(iterableArrayPattern20.ts, 0, 0))
>...new FooArrayIterator : Foo[]
>new FooArrayIterator : FooArrayIterator
>FooArrayIterator : typeof FooArrayIterator, Symbol(FooArrayIterator, Decl(iterableArrayPattern20.ts, 3, 27))
class Bar { x }
>Bar : Bar, Symbol(Bar, Decl(iterableArrayPattern20.ts, 1, 29))
>x : any, Symbol(x, Decl(iterableArrayPattern20.ts, 2, 11))
class Foo extends Bar { y }
>Foo : Foo, Symbol(Foo, Decl(iterableArrayPattern20.ts, 2, 15))
>Bar : Bar, Symbol(Bar, Decl(iterableArrayPattern20.ts, 1, 29))
>y : any, Symbol(y, Decl(iterableArrayPattern20.ts, 3, 23))
class FooArrayIterator {
>FooArrayIterator : FooArrayIterator, Symbol(FooArrayIterator, Decl(iterableArrayPattern20.ts, 3, 27))
next() {
>next : () => { value: Foo[]; done: boolean; }, Symbol(next, Decl(iterableArrayPattern20.ts, 4, 24))
return {
>{ value: [new Foo], done: false } : { value: Foo[]; done: boolean; }
value: [new Foo],
>value : Foo[], Symbol(value, Decl(iterableArrayPattern20.ts, 6, 16))
>[new Foo] : Foo[]
>new Foo : Foo
>Foo : typeof Foo, Symbol(Foo, Decl(iterableArrayPattern20.ts, 2, 15))
done: false
>done : boolean, Symbol(done, Decl(iterableArrayPattern20.ts, 7, 29))
>false : boolean
};
}
[Symbol.iterator]() {
>Symbol.iterator : symbol, Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1236, 31))
>Symbol : SymbolConstructor, Symbol(Symbol, Decl(lib.d.ts, 1186, 52), Decl(lib.d.ts, 1262, 11))
>iterator : symbol, Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1236, 31))
return this;
>this : FooArrayIterator, Symbol(FooArrayIterator, Decl(iterableArrayPattern20.ts, 3, 27))
}
}

View File

@@ -1,8 +1,11 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts(1,30): error TS2370: A rest parameter must be of an array type.
tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (1 errors) ====
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (2 errors) ====
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]) { }
~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2370: A rest parameter must be of an array type.
~~~~~~~~~~~~~~~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
takeFirstTwoEntries(new Map([["", 0], ["hello", 1]]));

View File

@@ -1,9 +1,12 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts(2,21): error TS2345: Argument of type 'Map<string, number>' is not assignable to parameter of type '[string, number]'.
Property '0' is missing in type 'Map<string, number>'.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts (1 errors) ====
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern26.ts (2 errors) ====
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { }
~~~~~~~~~~~~~~~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
takeFirstTwoEntries(new Map([["", 0], ["hello", 1]]));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type 'Map<string, number>' is not assignable to parameter of type '[string, number]'.

View File

@@ -0,0 +1,8 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern27.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern27.ts (1 errors) ====
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { }
~~~~~~~~~~~~~~~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
takeFirstTwoEntries(...new Map([["", 0], ["hello", 1]]));

View File

@@ -1,22 +0,0 @@
=== tests/cases/conformance/es6/destructuring/iterableArrayPattern27.ts ===
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { }
>takeFirstTwoEntries : (...[[k1, v1], [k2, v2]]: [string, number][]) => void, Symbol(takeFirstTwoEntries, Decl(iterableArrayPattern27.ts, 0, 0))
>k1 : string, Symbol(k1, Decl(iterableArrayPattern27.ts, 0, 34))
>v1 : number, Symbol(v1, Decl(iterableArrayPattern27.ts, 0, 37))
>k2 : string, Symbol(k2, Decl(iterableArrayPattern27.ts, 0, 44))
>v2 : number, Symbol(v2, Decl(iterableArrayPattern27.ts, 0, 47))
takeFirstTwoEntries(...new Map([["", 0], ["hello", 1]]));
>takeFirstTwoEntries(...new Map([["", 0], ["hello", 1]])) : void
>takeFirstTwoEntries : (...[[k1, v1], [k2, v2]]: [string, number][]) => void, Symbol(takeFirstTwoEntries, Decl(iterableArrayPattern27.ts, 0, 0))
>...new Map([["", 0], ["hello", 1]]) : [string, number]
>new Map([["", 0], ["hello", 1]]) : Map<string, number>
>Map : MapConstructor, Symbol(Map, Decl(lib.d.ts, 1837, 1), Decl(lib.d.ts, 1859, 11))
>[["", 0], ["hello", 1]] : [string, number][]
>["", 0] : [string, number]
>"" : string
>0 : number
>["hello", 1] : [string, number]
>"hello" : string
>1 : number

View File

@@ -1,9 +1,12 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,28): error TS2453: The type argument for type parameter 'V' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'boolean'.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (1 errors) ====
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (2 errors) ====
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { }
~~~~~~~~~~~~~~~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
takeFirstTwoEntries(...new Map([["", 0], ["hello", true]]));
~~~
!!! error TS2453: The type argument for type parameter 'V' cannot be inferred from the usage. Consider specifying the type arguments explicitly.

View File

@@ -1,10 +1,13 @@
tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts(1,33): error TS2501: A rest element cannot contain a binding pattern.
tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts(2,21): error TS2345: Argument of type '[string, boolean]' is not assignable to parameter of type '[string, number]'.
Types of property '1' are incompatible.
Type 'boolean' is not assignable to type 'number'.
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts (1 errors) ====
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts (2 errors) ====
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]: [string, number][]) { }
~~~~~~~~~~~~~~~~~~~~
!!! error TS2501: A rest element cannot contain a binding pattern.
takeFirstTwoEntries(...new Map([["", true], ["hello", true]]));
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '[string, boolean]' is not assignable to parameter of type '[string, number]'.