Skip to content

Commit eaf0d59

Browse files
author
Andy
authored
Fix bug: symbol.valueDeclaration not guaranteed to be defined (#26267)
1 parent 32e99ba commit eaf0d59

6 files changed

+95
-1
lines changed

src/compiler/checker.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20861,7 +20861,7 @@ namespace ts {
2086120861
// If func.parent is a class and symbol is a (readonly) property of that class, or
2086220862
// if func is a constructor and symbol is a (readonly) parameter property declared in it,
2086320863
// then symbol is writeable here.
20864-
return !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent);
20864+
return !symbol.valueDeclaration || !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent);
2086520865
}
2086620866
return true;
2086720867
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts(4,14): error TS2540: Cannot assign to 'attrib' because it is a constant or a read-only property.
2+
3+
4+
==== tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts (1 errors) ====
5+
class C extends (class {} as new () => Readonly<{ attrib: number }>) {
6+
constructor() {
7+
super()
8+
this.attrib = 2
9+
~~~~~~
10+
!!! error TS2540: Cannot assign to 'attrib' because it is a constant or a read-only property.
11+
}
12+
}
13+
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//// [readonlyAssignmentInSubclassOfClassExpression.ts]
2+
class C extends (class {} as new () => Readonly<{ attrib: number }>) {
3+
constructor() {
4+
super()
5+
this.attrib = 2
6+
}
7+
}
8+
9+
10+
//// [readonlyAssignmentInSubclassOfClassExpression.js]
11+
var __extends = (this && this.__extends) || (function () {
12+
var extendStatics = function (d, b) {
13+
extendStatics = Object.setPrototypeOf ||
14+
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
15+
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
16+
return extendStatics(d, b);
17+
}
18+
return function (d, b) {
19+
extendStatics(d, b);
20+
function __() { this.constructor = d; }
21+
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
22+
};
23+
})();
24+
var C = /** @class */ (function (_super) {
25+
__extends(C, _super);
26+
function C() {
27+
var _this = _super.call(this) || this;
28+
_this.attrib = 2;
29+
return _this;
30+
}
31+
return C;
32+
}(/** @class */ (function () {
33+
function class_1() {
34+
}
35+
return class_1;
36+
}())));
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
=== tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts ===
2+
class C extends (class {} as new () => Readonly<{ attrib: number }>) {
3+
>C : Symbol(C, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 0))
4+
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
5+
>attrib : Symbol(attrib, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 49))
6+
7+
constructor() {
8+
super()
9+
>super : Symbol(__type, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 28))
10+
11+
this.attrib = 2
12+
>this.attrib : Symbol(attrib, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 49))
13+
>this : Symbol(C, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 0))
14+
>attrib : Symbol(attrib, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 49))
15+
}
16+
}
17+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=== tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts ===
2+
class C extends (class {} as new () => Readonly<{ attrib: number }>) {
3+
>C : C
4+
>(class {} as new () => Readonly<{ attrib: number }>) : Readonly<{ attrib: number; }>
5+
>class {} as new () => Readonly<{ attrib: number }> : new () => Readonly<{ attrib: number; }>
6+
>class {} : typeof (Anonymous class)
7+
>attrib : number
8+
9+
constructor() {
10+
super()
11+
>super() : void
12+
>super : new () => Readonly<{ attrib: number; }>
13+
14+
this.attrib = 2
15+
>this.attrib = 2 : 2
16+
>this.attrib : any
17+
>this : this
18+
>attrib : any
19+
>2 : 2
20+
}
21+
}
22+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class C extends (class {} as new () => Readonly<{ attrib: number }>) {
2+
constructor() {
3+
super()
4+
this.attrib = 2
5+
}
6+
}

0 commit comments

Comments
 (0)