Skip to content

Commit 55a620c

Browse files
author
Andy
authored
Don't crash on computed property in destructure (#26334)
1 parent fce3d9f commit 55a620c

6 files changed

+118
-4
lines changed

src/compiler/checker.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24379,10 +24379,13 @@ namespace ts {
2437924379
const parentType = getTypeForBindingElementParent(parent);
2438024380
const name = node.propertyName || node.name;
2438124381
if (!isBindingPattern(name)) {
24382-
const property = getPropertyOfType(parentType!, getTextOfPropertyName(name))!; // TODO: GH#18217
24383-
markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
24384-
if (parent.initializer && property) {
24385-
checkPropertyAccessibility(parent, parent.initializer, parentType!, property);
24382+
const nameText = getTextOfPropertyName(name);
24383+
if (nameText) {
24384+
const property = getPropertyOfType(parentType!, nameText)!; // TODO: GH#18217
24385+
markPropertyAsReferenced(property, /*nodeForCheckWriteOnly*/ undefined, /*isThisAccess*/ false); // A destructuring is never a write-only reference.
24386+
if (parent.initializer && property) {
24387+
checkPropertyAccessibility(parent, parent.initializer, parentType!, property);
24388+
}
2438624389
}
2438724390
}
2438824391
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
tests/cases/compiler/destructureComputedProperty.ts(8,7): error TS2341: Property 'p' is private and only accessible within class 'C'.
2+
3+
4+
==== tests/cases/compiler/destructureComputedProperty.ts (1 errors) ====
5+
declare const ab: { n: number } | { n: string };
6+
const nameN = "n";
7+
const { [nameN]: n } = ab;
8+
9+
class C { private p: number; }
10+
const nameP = "p";
11+
const { [nameP]: p } = new C();
12+
const { p: p2 } = new C();
13+
~~~~~~~~~
14+
!!! error TS2341: Property 'p' is private and only accessible within class 'C'.
15+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
//// [destructureComputedProperty.ts]
2+
declare const ab: { n: number } | { n: string };
3+
const nameN = "n";
4+
const { [nameN]: n } = ab;
5+
6+
class C { private p: number; }
7+
const nameP = "p";
8+
const { [nameP]: p } = new C();
9+
const { p: p2 } = new C();
10+
11+
12+
//// [destructureComputedProperty.js]
13+
var nameN = "n";
14+
var _a = nameN, n = ab[_a];
15+
var C = /** @class */ (function () {
16+
function C() {
17+
}
18+
return C;
19+
}());
20+
var nameP = "p";
21+
var _b = nameP, p = new C()[_b];
22+
var p2 = new C().p;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
=== tests/cases/compiler/destructureComputedProperty.ts ===
2+
declare const ab: { n: number } | { n: string };
3+
>ab : Symbol(ab, Decl(destructureComputedProperty.ts, 0, 13))
4+
>n : Symbol(n, Decl(destructureComputedProperty.ts, 0, 19))
5+
>n : Symbol(n, Decl(destructureComputedProperty.ts, 0, 35))
6+
7+
const nameN = "n";
8+
>nameN : Symbol(nameN, Decl(destructureComputedProperty.ts, 1, 5))
9+
10+
const { [nameN]: n } = ab;
11+
>nameN : Symbol(nameN, Decl(destructureComputedProperty.ts, 1, 5))
12+
>n : Symbol(n, Decl(destructureComputedProperty.ts, 2, 7))
13+
>ab : Symbol(ab, Decl(destructureComputedProperty.ts, 0, 13))
14+
15+
class C { private p: number; }
16+
>C : Symbol(C, Decl(destructureComputedProperty.ts, 2, 26))
17+
>p : Symbol(C.p, Decl(destructureComputedProperty.ts, 4, 9))
18+
19+
const nameP = "p";
20+
>nameP : Symbol(nameP, Decl(destructureComputedProperty.ts, 5, 5))
21+
22+
const { [nameP]: p } = new C();
23+
>nameP : Symbol(nameP, Decl(destructureComputedProperty.ts, 5, 5))
24+
>p : Symbol(p, Decl(destructureComputedProperty.ts, 6, 7))
25+
>C : Symbol(C, Decl(destructureComputedProperty.ts, 2, 26))
26+
27+
const { p: p2 } = new C();
28+
>p : Symbol(C.p, Decl(destructureComputedProperty.ts, 4, 9))
29+
>p2 : Symbol(p2, Decl(destructureComputedProperty.ts, 7, 7))
30+
>C : Symbol(C, Decl(destructureComputedProperty.ts, 2, 26))
31+
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
=== tests/cases/compiler/destructureComputedProperty.ts ===
2+
declare const ab: { n: number } | { n: string };
3+
>ab : { n: number; } | { n: string; }
4+
>n : number
5+
>n : string
6+
7+
const nameN = "n";
8+
>nameN : "n"
9+
>"n" : "n"
10+
11+
const { [nameN]: n } = ab;
12+
>nameN : "n"
13+
>n : string | number
14+
>ab : { n: number; } | { n: string; }
15+
16+
class C { private p: number; }
17+
>C : C
18+
>p : number
19+
20+
const nameP = "p";
21+
>nameP : "p"
22+
>"p" : "p"
23+
24+
const { [nameP]: p } = new C();
25+
>nameP : "p"
26+
>p : number
27+
>new C() : C
28+
>C : typeof C
29+
30+
const { p: p2 } = new C();
31+
>p : any
32+
>p2 : number
33+
>new C() : C
34+
>C : typeof C
35+
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
declare const ab: { n: number } | { n: string };
2+
const nameN = "n";
3+
const { [nameN]: n } = ab;
4+
5+
class C { private p: number; }
6+
const nameP = "p";
7+
const { [nameP]: p } = new C();
8+
const { p: p2 } = new C();

0 commit comments

Comments
 (0)