Skip to content

Commit 38b5379

Browse files
ajafffelibarzilay
authored andcommitted
Allow destructuring the same property multiple times
Fixes: #35939
1 parent 9889c74 commit 38b5379

File tree

6 files changed

+71
-19
lines changed

6 files changed

+71
-19
lines changed

src/compiler/binder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1865,7 +1865,7 @@ namespace ts {
18651865
Accessor = 2
18661866
}
18671867

1868-
if (inStrictMode) {
1868+
if (inStrictMode && !isAssignmentTarget(node)) {
18691869
const seen = createUnderscoreEscapedMap<ElementKind>();
18701870

18711871
for (const prop of node.properties) {

src/compiler/checker.ts

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -35968,30 +35968,32 @@ namespace ts {
3596835968
throw Debug.assertNever(prop, "Unexpected syntax kind:" + (<Node>prop).kind);
3596935969
}
3597035970

35971-
const effectiveName = getPropertyNameForPropertyNameNode(name);
35972-
if (effectiveName === undefined) {
35973-
continue;
35974-
}
35971+
if (!inDestructuring) {
35972+
const effectiveName = getPropertyNameForPropertyNameNode(name);
35973+
if (effectiveName === undefined) {
35974+
continue;
35975+
}
3597535976

35976-
const existingKind = seen.get(effectiveName);
35977-
if (!existingKind) {
35978-
seen.set(effectiveName, currentKind);
35979-
}
35980-
else {
35981-
if ((currentKind & DeclarationMeaning.PropertyAssignmentOrMethod) && (existingKind & DeclarationMeaning.PropertyAssignmentOrMethod)) {
35982-
grammarErrorOnNode(name, Diagnostics.Duplicate_identifier_0, getTextOfNode(name));
35977+
const existingKind = seen.get(effectiveName);
35978+
if (!existingKind) {
35979+
seen.set(effectiveName, currentKind);
3598335980
}
35984-
else if ((currentKind & DeclarationMeaning.GetOrSetAccessor) && (existingKind & DeclarationMeaning.GetOrSetAccessor)) {
35985-
if (existingKind !== DeclarationMeaning.GetOrSetAccessor && currentKind !== existingKind) {
35986-
seen.set(effectiveName, currentKind | existingKind);
35981+
else {
35982+
if ((currentKind & DeclarationMeaning.PropertyAssignmentOrMethod) && (existingKind & DeclarationMeaning.PropertyAssignmentOrMethod)) {
35983+
grammarErrorOnNode(name, Diagnostics.Duplicate_identifier_0, getTextOfNode(name));
35984+
}
35985+
else if ((currentKind & DeclarationMeaning.GetOrSetAccessor) && (existingKind & DeclarationMeaning.GetOrSetAccessor)) {
35986+
if (existingKind !== DeclarationMeaning.GetOrSetAccessor && currentKind !== existingKind) {
35987+
seen.set(effectiveName, currentKind | existingKind);
35988+
}
35989+
else {
35990+
return grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
35991+
}
3598735992
}
3598835993
else {
35989-
return grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_multiple_get_Slashset_accessors_with_the_same_name);
35994+
return grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
3599035995
}
3599135996
}
35992-
else {
35993-
return grammarErrorOnNode(name, Diagnostics.An_object_literal_cannot_have_property_and_accessor_with_the_same_name);
35994-
}
3599535997
}
3599635998
}
3599735999
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
//// [destructuringSamePropertyTwice.ts]
2+
'use strict';
3+
let { foo, foo: bar } = { foo: 1 };
4+
({ foo, foo: bar } = { foo: 2 });
5+
6+
//// [destructuringSamePropertyTwice.js]
7+
'use strict';
8+
var _a;
9+
var _b = { foo: 1 }, foo = _b.foo, bar = _b.foo;
10+
(_a = { foo: 2 }, foo = _a.foo, bar = _a.foo);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
=== tests/cases/conformance/es6/destructuring/destructuringSamePropertyTwice.ts ===
2+
'use strict';
3+
let { foo, foo: bar } = { foo: 1 };
4+
>foo : Symbol(foo, Decl(destructuringSamePropertyTwice.ts, 1, 5))
5+
>foo : Symbol(foo, Decl(destructuringSamePropertyTwice.ts, 1, 25))
6+
>bar : Symbol(bar, Decl(destructuringSamePropertyTwice.ts, 1, 10))
7+
>foo : Symbol(foo, Decl(destructuringSamePropertyTwice.ts, 1, 25))
8+
9+
({ foo, foo: bar } = { foo: 2 });
10+
>foo : Symbol(foo, Decl(destructuringSamePropertyTwice.ts, 2, 2), Decl(destructuringSamePropertyTwice.ts, 2, 7))
11+
>foo : Symbol(foo, Decl(destructuringSamePropertyTwice.ts, 2, 2), Decl(destructuringSamePropertyTwice.ts, 2, 7))
12+
>bar : Symbol(bar, Decl(destructuringSamePropertyTwice.ts, 1, 10))
13+
>foo : Symbol(foo, Decl(destructuringSamePropertyTwice.ts, 2, 22))
14+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
=== tests/cases/conformance/es6/destructuring/destructuringSamePropertyTwice.ts ===
2+
'use strict';
3+
>'use strict' : "use strict"
4+
5+
let { foo, foo: bar } = { foo: 1 };
6+
>foo : number
7+
>foo : any
8+
>bar : number
9+
>{ foo: 1 } : { foo: number; }
10+
>foo : number
11+
>1 : 1
12+
13+
({ foo, foo: bar } = { foo: 2 });
14+
>({ foo, foo: bar } = { foo: 2 }) : { foo: number; }
15+
>{ foo, foo: bar } = { foo: 2 } : { foo: number; }
16+
>{ foo, foo: bar } : { foo: number; }
17+
>foo : number
18+
>foo : number
19+
>bar : number
20+
>{ foo: 2 } : { foo: number; }
21+
>foo : number
22+
>2 : 2
23+
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
'use strict';
2+
let { foo, foo: bar } = { foo: 1 };
3+
({ foo, foo: bar } = { foo: 2 });

0 commit comments

Comments
 (0)