Skip to content

Commit 34dd773

Browse files
authored
Merge pull request #24672 from bakkot/binding-comma
Allow trailing commas after non-rest elements in destructuring
2 parents 30994c8 + 87bb5e3 commit 34dd773

6 files changed

+78
-3
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20046,7 +20046,6 @@ namespace ts {
2004620046

2004720047
function checkObjectLiteralAssignment(node: ObjectLiteralExpression, sourceType: Type): Type {
2004820048
const properties = node.properties;
20049-
checkGrammarForDisallowedTrailingComma(properties, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
2005020049
if (strictNullChecks && properties.length === 0) {
2005120050
return checkNonNullType(sourceType, node);
2005220051
}
@@ -20057,7 +20056,7 @@ namespace ts {
2005720056
}
2005820057

2005920058
/** Note: If property cannot be a SpreadAssignment, then allProperties does not need to be provided */
20060-
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: ReadonlyArray<ObjectLiteralElementLike>) {
20059+
function checkObjectLiteralDestructuringPropertyAssignment(objectLiteralType: Type, property: ObjectLiteralElementLike, allProperties?: NodeArray<ObjectLiteralElementLike>) {
2006120060
if (property.kind === SyntaxKind.PropertyAssignment || property.kind === SyntaxKind.ShorthandPropertyAssignment) {
2006220061
const name = property.name;
2006320062
if (name.kind === SyntaxKind.ComputedPropertyName) {
@@ -20097,6 +20096,7 @@ namespace ts {
2009720096
}
2009820097
}
2009920098
const type = getRestType(objectLiteralType, nonRestNames, objectLiteralType.symbol);
20099+
checkGrammarForDisallowedTrailingComma(allProperties, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
2010020100
return checkDestructuringAssignment(property.expression, type);
2010120101
}
2010220102
else {
@@ -20106,7 +20106,6 @@ namespace ts {
2010620106

2010720107
function checkArrayLiteralAssignment(node: ArrayLiteralExpression, sourceType: Type, checkMode?: CheckMode): Type {
2010820108
const elements = node.elements;
20109-
checkGrammarForDisallowedTrailingComma(elements, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
2011020109
if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
2011120110
checkExternalEmitHelpers(node, ExternalEmitHelpers.Read);
2011220111
}
@@ -20158,6 +20157,7 @@ namespace ts {
2015820157
error((<BinaryExpression>restExpression).operatorToken, Diagnostics.A_rest_element_cannot_have_an_initializer);
2015920158
}
2016020159
else {
20160+
checkGrammarForDisallowedTrailingComma(node.elements, Diagnostics.A_rest_parameter_or_binding_pattern_may_not_have_a_trailing_comma);
2016120161
return checkDestructuringAssignment(restExpression, createArrayType(elementType), checkMode);
2016220162
}
2016320163
}

tests/baselines/reference/trailingCommasInBindingPatterns.errors.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,11 @@ tests/cases/conformance/es7/trailingCommasInBindingPatterns.ts(5,7): error TS101
1818
({...d,} = {});
1919
~
2020
!!! error TS1013: A rest parameter or binding pattern may not have a trailing comma.
21+
22+
// Allowed for non-rest elements
23+
const [e,] = <any>[];
24+
const {f,} = <any>{};
25+
let g, h;
26+
([g,] = <any>[]);
27+
({h,} = <any>{});
2128

tests/baselines/reference/trailingCommasInBindingPatterns.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,13 @@ const {...b,} = {};
44
let c, d;
55
([...c,] = []);
66
({...d,} = {});
7+
8+
// Allowed for non-rest elements
9+
const [e,] = <any>[];
10+
const {f,} = <any>{};
11+
let g, h;
12+
([g,] = <any>[]);
13+
({h,} = <any>{});
714

815

916
//// [trailingCommasInBindingPatterns.js]
@@ -21,3 +28,9 @@ var b = __rest({}, []);
2128
var c, d;
2229
(c = [].slice(0));
2330
(d = __rest({}, []));
31+
// Allowed for non-rest elements
32+
var e = [][0];
33+
var f = {}.f;
34+
var g, h;
35+
(g = [][0]);
36+
(h = {}.h);

tests/baselines/reference/trailingCommasInBindingPatterns.symbols

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,20 @@ let c, d;
1515
({...d,} = {});
1616
>d : Symbol(d, Decl(trailingCommasInBindingPatterns.ts, 2, 6))
1717

18+
// Allowed for non-rest elements
19+
const [e,] = <any>[];
20+
>e : Symbol(e, Decl(trailingCommasInBindingPatterns.ts, 7, 7))
21+
22+
const {f,} = <any>{};
23+
>f : Symbol(f, Decl(trailingCommasInBindingPatterns.ts, 8, 7))
24+
25+
let g, h;
26+
>g : Symbol(g, Decl(trailingCommasInBindingPatterns.ts, 9, 3))
27+
>h : Symbol(h, Decl(trailingCommasInBindingPatterns.ts, 9, 6))
28+
29+
([g,] = <any>[]);
30+
>g : Symbol(g, Decl(trailingCommasInBindingPatterns.ts, 9, 3))
31+
32+
({h,} = <any>{});
33+
>h : Symbol(h, Decl(trailingCommasInBindingPatterns.ts, 11, 2))
34+

tests/baselines/reference/trailingCommasInBindingPatterns.types

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,34 @@ let c, d;
2626
>d : any
2727
>{} : {}
2828

29+
// Allowed for non-rest elements
30+
const [e,] = <any>[];
31+
>e : any
32+
><any>[] : any
33+
>[] : undefined[]
34+
35+
const {f,} = <any>{};
36+
>f : any
37+
><any>{} : any
38+
>{} : {}
39+
40+
let g, h;
41+
>g : any
42+
>h : any
43+
44+
([g,] = <any>[]);
45+
>([g,] = <any>[]) : any
46+
>[g,] = <any>[] : any
47+
>[g,] : [any]
48+
>g : any
49+
><any>[] : any
50+
>[] : undefined[]
51+
52+
({h,} = <any>{});
53+
>({h,} = <any>{}) : any
54+
>{h,} = <any>{} : any
55+
>{h,} : { h: any; }
56+
>h : any
57+
><any>{} : any
58+
>{} : {}
59+

tests/cases/conformance/es7/trailingCommasInBindingPatterns.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,10 @@ const {...b,} = {};
33
let c, d;
44
([...c,] = []);
55
({...d,} = {});
6+
7+
// Allowed for non-rest elements
8+
const [e,] = <any>[];
9+
const {f,} = <any>{};
10+
let g, h;
11+
([g,] = <any>[]);
12+
({h,} = <any>{});

0 commit comments

Comments
 (0)