Skip to content

Commit 1236a10

Browse files
authored
Fix initialization error when destructuring from object literal that includes a spread assignment (microsoft#36865)
* Add test * Fix superfluous error when destructuring from object that includes spread assignment * Update baseline to include error case * Remove redundant check
1 parent 50e9c15 commit 1236a10

File tree

6 files changed

+257
-2
lines changed

6 files changed

+257
-2
lines changed

src/compiler/checker.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22546,9 +22546,11 @@ namespace ts {
2254622546

2254722547
// If object literal is contextually typed by the implied type of a binding pattern, augment the result
2254822548
// type with those properties for which the binding pattern specifies a default value.
22549-
if (contextualTypeHasPattern) {
22549+
// If the object literal is spread into another object literal, skip this step and let the top-level object
22550+
// literal handle it instead.
22551+
if (contextualTypeHasPattern && node.parent.kind !== SyntaxKind.SpreadAssignment) {
2255022552
for (const prop of getPropertiesOfType(contextualType!)) {
22551-
if (!propertiesTable.get(prop.escapedName) && !(spread && getPropertyOfType(spread, prop.escapedName))) {
22553+
if (!propertiesTable.get(prop.escapedName) && !getPropertyOfType(spread, prop.escapedName)) {
2255222554
if (!(prop.flags & SymbolFlags.Optional)) {
2255322555
error(prop.valueDeclaration || (<TransientSymbol>prop).bindingElement,
2255422556
Diagnostics.Initializer_provides_no_value_for_this_binding_element_and_the_binding_element_has_no_default_value);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
tests/cases/conformance/es6/destructuring/destructuringSpread.ts(16,21): error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
2+
3+
4+
==== tests/cases/conformance/es6/destructuring/destructuringSpread.ts (1 errors) ====
5+
const { x } = {
6+
...{},
7+
x: 0
8+
};
9+
10+
const { y } = {
11+
y: 0,
12+
...{}
13+
};
14+
15+
const { z, a, b } = {
16+
z: 0,
17+
...{ a: 0, b: 0 }
18+
};
19+
20+
const { c, d, e, f, g } = {
21+
~
22+
!!! error TS2525: Initializer provides no value for this binding element and the binding element has no default value.
23+
...{
24+
...{
25+
...{
26+
c: 0,
27+
},
28+
d: 0
29+
},
30+
e: 0
31+
},
32+
f: 0
33+
};
34+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
//// [destructuringSpread.ts]
2+
const { x } = {
3+
...{},
4+
x: 0
5+
};
6+
7+
const { y } = {
8+
y: 0,
9+
...{}
10+
};
11+
12+
const { z, a, b } = {
13+
z: 0,
14+
...{ a: 0, b: 0 }
15+
};
16+
17+
const { c, d, e, f, g } = {
18+
...{
19+
...{
20+
...{
21+
c: 0,
22+
},
23+
d: 0
24+
},
25+
e: 0
26+
},
27+
f: 0
28+
};
29+
30+
31+
//// [destructuringSpread.js]
32+
var __assign = (this && this.__assign) || function () {
33+
__assign = Object.assign || function(t) {
34+
for (var s, i = 1, n = arguments.length; i < n; i++) {
35+
s = arguments[i];
36+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
37+
t[p] = s[p];
38+
}
39+
return t;
40+
};
41+
return __assign.apply(this, arguments);
42+
};
43+
var x = __assign({}, { x: 0 }).x;
44+
var y = __assign({ y: 0 }, {}).y;
45+
var _a = __assign({ z: 0 }, { a: 0, b: 0 }), z = _a.z, a = _a.a, b = _a.b;
46+
var _b = __assign(__assign({}, __assign(__assign({}, __assign({
47+
c: 0
48+
}, { d: 0 })), { e: 0 })), { f: 0 }), c = _b.c, d = _b.d, e = _b.e, f = _b.f, g = _b.g;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
=== tests/cases/conformance/es6/destructuring/destructuringSpread.ts ===
2+
const { x } = {
3+
>x : Symbol(x, Decl(destructuringSpread.ts, 0, 7))
4+
5+
...{},
6+
x: 0
7+
>x : Symbol(x, Decl(destructuringSpread.ts, 1, 8))
8+
9+
};
10+
11+
const { y } = {
12+
>y : Symbol(y, Decl(destructuringSpread.ts, 5, 7))
13+
14+
y: 0,
15+
>y : Symbol(y, Decl(destructuringSpread.ts, 5, 15))
16+
17+
...{}
18+
};
19+
20+
const { z, a, b } = {
21+
>z : Symbol(z, Decl(destructuringSpread.ts, 10, 7))
22+
>a : Symbol(a, Decl(destructuringSpread.ts, 10, 10))
23+
>b : Symbol(b, Decl(destructuringSpread.ts, 10, 13))
24+
25+
z: 0,
26+
>z : Symbol(z, Decl(destructuringSpread.ts, 10, 21))
27+
28+
...{ a: 0, b: 0 }
29+
>a : Symbol(a, Decl(destructuringSpread.ts, 12, 6))
30+
>b : Symbol(b, Decl(destructuringSpread.ts, 12, 12))
31+
32+
};
33+
34+
const { c, d, e, f, g } = {
35+
>c : Symbol(c, Decl(destructuringSpread.ts, 15, 7))
36+
>d : Symbol(d, Decl(destructuringSpread.ts, 15, 10))
37+
>e : Symbol(e, Decl(destructuringSpread.ts, 15, 13))
38+
>f : Symbol(f, Decl(destructuringSpread.ts, 15, 16))
39+
>g : Symbol(g, Decl(destructuringSpread.ts, 15, 19))
40+
41+
...{
42+
...{
43+
...{
44+
c: 0,
45+
>c : Symbol(c, Decl(destructuringSpread.ts, 18, 10))
46+
47+
},
48+
d: 0
49+
>d : Symbol(d, Decl(destructuringSpread.ts, 20, 8))
50+
51+
},
52+
e: 0
53+
>e : Symbol(e, Decl(destructuringSpread.ts, 22, 6))
54+
55+
},
56+
f: 0
57+
>f : Symbol(f, Decl(destructuringSpread.ts, 24, 4))
58+
59+
};
60+
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
=== tests/cases/conformance/es6/destructuring/destructuringSpread.ts ===
2+
const { x } = {
3+
>x : number
4+
>{ ...{}, x: 0} : { x: number; }
5+
6+
...{},
7+
>{} : {}
8+
9+
x: 0
10+
>x : number
11+
>0 : 0
12+
13+
};
14+
15+
const { y } = {
16+
>y : number
17+
>{ y: 0, ...{}} : { y: number; }
18+
19+
y: 0,
20+
>y : number
21+
>0 : 0
22+
23+
...{}
24+
>{} : {}
25+
26+
};
27+
28+
const { z, a, b } = {
29+
>z : number
30+
>a : number
31+
>b : number
32+
>{ z: 0, ...{ a: 0, b: 0 }} : { a: number; b: number; z: number; }
33+
34+
z: 0,
35+
>z : number
36+
>0 : 0
37+
38+
...{ a: 0, b: 0 }
39+
>{ a: 0, b: 0 } : { a: number; b: number; }
40+
>a : number
41+
>0 : 0
42+
>b : number
43+
>0 : 0
44+
45+
};
46+
47+
const { c, d, e, f, g } = {
48+
>c : number
49+
>d : number
50+
>e : number
51+
>f : number
52+
>g : any
53+
>{ ...{ ...{ ...{ c: 0, }, d: 0 }, e: 0 }, f: 0} : { f: number; g: any; e: number; d: number; c: number; }
54+
55+
...{
56+
>{ ...{ ...{ c: 0, }, d: 0 }, e: 0 } : { e: number; d: number; c: number; }
57+
58+
...{
59+
>{ ...{ c: 0, }, d: 0 } : { d: number; c: number; }
60+
61+
...{
62+
>{ c: 0, } : { c: number; }
63+
64+
c: 0,
65+
>c : number
66+
>0 : 0
67+
68+
},
69+
d: 0
70+
>d : number
71+
>0 : 0
72+
73+
},
74+
e: 0
75+
>e : number
76+
>0 : 0
77+
78+
},
79+
f: 0
80+
>f : number
81+
>0 : 0
82+
83+
};
84+
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const { x } = {
2+
...{},
3+
x: 0
4+
};
5+
6+
const { y } = {
7+
y: 0,
8+
...{}
9+
};
10+
11+
const { z, a, b } = {
12+
z: 0,
13+
...{ a: 0, b: 0 }
14+
};
15+
16+
const { c, d, e, f, g } = {
17+
...{
18+
...{
19+
...{
20+
c: 0,
21+
},
22+
d: 0
23+
},
24+
e: 0
25+
},
26+
f: 0
27+
};

0 commit comments

Comments
 (0)