mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
allow BindingPattern in FunctionRestParameter
also add downlevel emit for the destructured rest param Part of #6275
This commit is contained in:
@@ -28570,10 +28570,6 @@ namespace ts {
|
||||
checkGrammarForDisallowedTrailingComma(parameters, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
|
||||
}
|
||||
|
||||
if (isBindingPattern(parameter.name)) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -1340,8 +1340,8 @@ namespace ts {
|
||||
* part of a constructor declaration with a
|
||||
* synthesized call to `super`
|
||||
*/
|
||||
function shouldAddRestParameter(node: ParameterDeclaration | undefined, inConstructorWithSynthesizedSuper: boolean) {
|
||||
return node && node.dotDotDotToken && node.name.kind === SyntaxKind.Identifier && !inConstructorWithSynthesizedSuper;
|
||||
function shouldAddRestParameter(node: ParameterDeclaration | undefined, inConstructorWithSynthesizedSuper: boolean): node is ParameterDeclaration {
|
||||
return !!(node && node.dotDotDotToken && !inConstructorWithSynthesizedSuper);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1360,11 +1360,11 @@ namespace ts {
|
||||
}
|
||||
|
||||
// `declarationName` is the name of the local declaration for the parameter.
|
||||
const declarationName = getMutableClone(<Identifier>parameter!.name);
|
||||
const declarationName = parameter.name.kind === SyntaxKind.Identifier ? getMutableClone(parameter.name) : createTempVariable(/*recordTempVariable*/ undefined);
|
||||
setEmitFlags(declarationName, EmitFlags.NoSourceMap);
|
||||
|
||||
// `expressionName` is the name of the parameter used in expressions.
|
||||
const expressionName = getSynthesizedClone(<Identifier>parameter!.name);
|
||||
const expressionName = parameter.name.kind === SyntaxKind.Identifier ? getSynthesizedClone(parameter.name) : declarationName;
|
||||
const restIndex = node.parameters.length - 1;
|
||||
const temp = createLoopVariable();
|
||||
|
||||
@@ -1429,6 +1429,24 @@ namespace ts {
|
||||
setEmitFlags(forStatement, EmitFlags.CustomPrologue);
|
||||
startOnNewLine(forStatement);
|
||||
statements.push(forStatement);
|
||||
|
||||
if (parameter.name.kind !== SyntaxKind.Identifier) {
|
||||
// do the actual destructuring of the rest parameter if necessary
|
||||
statements.push(
|
||||
setEmitFlags(
|
||||
setTextRange(
|
||||
createVariableStatement(
|
||||
/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(
|
||||
flattenDestructuringBinding(parameter, visitor, context, FlattenLevel.All, expressionName),
|
||||
)
|
||||
),
|
||||
parameter
|
||||
),
|
||||
EmitFlags.CustomPrologue
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts(16,17): error TS2501: A rest element cannot contain a binding pattern.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern14.ts (1 errors) ====
|
||||
class Bar { x }
|
||||
class Foo extends Bar { y }
|
||||
class FooIterator {
|
||||
next() {
|
||||
return {
|
||||
value: new Foo,
|
||||
done: false
|
||||
};
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
function fun(...[a, ...b]) { }
|
||||
~~~~~~~~~
|
||||
!!! error TS2501: A rest element cannot contain a binding pattern.
|
||||
fun(new FooIterator);
|
||||
@@ -1,23 +0,0 @@
|
||||
tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts(16,17): error TS2501: A rest element cannot contain a binding pattern.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern15.ts (1 errors) ====
|
||||
class Bar { x }
|
||||
class Foo extends Bar { y }
|
||||
class FooIterator {
|
||||
next() {
|
||||
return {
|
||||
value: new Foo,
|
||||
done: false
|
||||
};
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
function fun(...[a, b]: Bar[]) { }
|
||||
~~~~~~
|
||||
!!! error TS2501: A rest element cannot contain a binding pattern.
|
||||
fun(...new FooIterator);
|
||||
@@ -1,13 +1,10 @@
|
||||
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(2,12): error TS2449: Class 'FooIteratorIterator' used before its declaration.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern16.ts (3 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]'.
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(16,17): error TS2501: A rest element cannot contain a binding pattern.
|
||||
tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(17,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 (2 errors) ====
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts (1 errors) ====
|
||||
class Bar { x }
|
||||
class Foo extends Bar { y }
|
||||
class FooIterator {
|
||||
@@ -20,8 +19,6 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern17.ts(17,5): error
|
||||
}
|
||||
|
||||
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'.
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts(16,17): error TS2501: A rest element cannot contain a binding pattern.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern20.ts (1 errors) ====
|
||||
class Bar { x }
|
||||
class Foo extends Bar { y }
|
||||
class FooArrayIterator {
|
||||
next() {
|
||||
return {
|
||||
value: [new Foo],
|
||||
done: false
|
||||
};
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
function fun(...[[a = new Foo], b = [new Foo]]: Bar[][]) { }
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2501: A rest element cannot contain a binding pattern.
|
||||
fun(...new FooArrayIterator);
|
||||
@@ -1,11 +1,8 @@
|
||||
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(2,1): error TS2554: Expected 2 arguments, but got 1.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (2 errors) ====
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern25.ts (1 errors) ====
|
||||
function takeFirstTwoEntries(...[[k1, v1], [k2, v2]]) { }
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2501: A rest element cannot contain a binding pattern.
|
||||
takeFirstTwoEntries(new Map([["", 0], ["hello", 1]]));
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2554: Expected 2 arguments, but got 1.
|
||||
@@ -1,12 +1,9 @@
|
||||
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 (2 errors) ====
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern26.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]]));
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type 'Map<string, number>' is not assignable to parameter of type '[string, number]'.
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
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]]));
|
||||
@@ -1,4 +1,3 @@
|
||||
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,32): error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'.
|
||||
Types of property 'concat' are incompatible.
|
||||
Type '{ (...items: ConcatArray<[string, number] | [string, boolean]>[]): ([string, number] | [string, boolean])[]; (...items: ([string, number] | [string, boolean] | ConcatArray<[string, number] | [string, boolean]>)[]): ([string, number] | [string, boolean])[]; }' is not assignable to type '{ (...items: ConcatArray<[string, number]>[]): [string, number][]; (...items: ([string, number] | ConcatArray<[string, number]>)[]): [string, number][]; }'.
|
||||
@@ -8,10 +7,8 @@ tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts(2,32): error
|
||||
Type 'boolean' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.ts (2 errors) ====
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern28.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", true]]));
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '([string, number] | [string, boolean])[]' is not assignable to parameter of type 'ReadonlyArray<[string, number]>'.
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
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]'.
|
||||
Type 'boolean' is not assignable to type 'number'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts (2 errors) ====
|
||||
==== tests/cases/conformance/es6/destructuring/iterableArrayPattern29.ts (1 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]'.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
tests/cases/compiler/restParameterWithBindingPattern1.ts(1,15): error TS2501: A rest element cannot contain a binding pattern.
|
||||
|
||||
|
||||
==== tests/cases/compiler/restParameterWithBindingPattern1.ts (1 errors) ====
|
||||
function a(...{a, b}) { }
|
||||
~~~~~~
|
||||
!!! error TS2501: A rest element cannot contain a binding pattern.
|
||||
@@ -2,4 +2,10 @@
|
||||
function a(...{a, b}) { }
|
||||
|
||||
//// [restParameterWithBindingPattern1.js]
|
||||
function a() { }
|
||||
function a() {
|
||||
var _a = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
_a[_i] = arguments[_i];
|
||||
}
|
||||
var a = _a.a, b = _a.b;
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
tests/cases/compiler/restParameterWithBindingPattern2.ts(1,15): error TS2501: A rest element cannot contain a binding pattern.
|
||||
|
||||
|
||||
==== tests/cases/compiler/restParameterWithBindingPattern2.ts (1 errors) ====
|
||||
function a(...[a, b]) { }
|
||||
~~~~~~
|
||||
!!! error TS2501: A rest element cannot contain a binding pattern.
|
||||
@@ -2,4 +2,10 @@
|
||||
function a(...[a, b]) { }
|
||||
|
||||
//// [restParameterWithBindingPattern2.js]
|
||||
function a() { }
|
||||
function a() {
|
||||
var _a = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
_a[_i] = arguments[_i];
|
||||
}
|
||||
var a = _a[0], b = _a[1];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user