diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2b93a80b3b..71fd9ca42e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20861,7 +20861,7 @@ namespace ts { // If func.parent is a class and symbol is a (readonly) property of that class, or // if func is a constructor and symbol is a (readonly) parameter property declared in it, // then symbol is writeable here. - return !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent); + return !symbol.valueDeclaration || !(func.parent === symbol.valueDeclaration.parent || func === symbol.valueDeclaration.parent); } return true; } diff --git a/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.errors.txt b/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.errors.txt new file mode 100644 index 0000000000..760cee5402 --- /dev/null +++ b/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.errors.txt @@ -0,0 +1,13 @@ +tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts(4,14): error TS2540: Cannot assign to 'attrib' because it is a constant or a read-only property. + + +==== tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts (1 errors) ==== + class C extends (class {} as new () => Readonly<{ attrib: number }>) { + constructor() { + super() + this.attrib = 2 + ~~~~~~ +!!! error TS2540: Cannot assign to 'attrib' because it is a constant or a read-only property. + } + } + \ No newline at end of file diff --git a/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.js b/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.js new file mode 100644 index 0000000000..db353993a4 --- /dev/null +++ b/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.js @@ -0,0 +1,36 @@ +//// [readonlyAssignmentInSubclassOfClassExpression.ts] +class C extends (class {} as new () => Readonly<{ attrib: number }>) { + constructor() { + super() + this.attrib = 2 + } +} + + +//// [readonlyAssignmentInSubclassOfClassExpression.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = function (d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + } + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var C = /** @class */ (function (_super) { + __extends(C, _super); + function C() { + var _this = _super.call(this) || this; + _this.attrib = 2; + return _this; + } + return C; +}(/** @class */ (function () { + function class_1() { + } + return class_1; +}()))); diff --git a/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.symbols b/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.symbols new file mode 100644 index 0000000000..96abda3031 --- /dev/null +++ b/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.symbols @@ -0,0 +1,17 @@ +=== tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts === +class C extends (class {} as new () => Readonly<{ attrib: number }>) { +>C : Symbol(C, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 0)) +>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --)) +>attrib : Symbol(attrib, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 49)) + + constructor() { + super() +>super : Symbol(__type, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 28)) + + this.attrib = 2 +>this.attrib : Symbol(attrib, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 49)) +>this : Symbol(C, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 0)) +>attrib : Symbol(attrib, Decl(readonlyAssignmentInSubclassOfClassExpression.ts, 0, 49)) + } +} + diff --git a/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.types b/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.types new file mode 100644 index 0000000000..bdeb79aaac --- /dev/null +++ b/tests/baselines/reference/readonlyAssignmentInSubclassOfClassExpression.types @@ -0,0 +1,22 @@ +=== tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts === +class C extends (class {} as new () => Readonly<{ attrib: number }>) { +>C : C +>(class {} as new () => Readonly<{ attrib: number }>) : Readonly<{ attrib: number; }> +>class {} as new () => Readonly<{ attrib: number }> : new () => Readonly<{ attrib: number; }> +>class {} : typeof (Anonymous class) +>attrib : number + + constructor() { + super() +>super() : void +>super : new () => Readonly<{ attrib: number; }> + + this.attrib = 2 +>this.attrib = 2 : 2 +>this.attrib : any +>this : this +>attrib : any +>2 : 2 + } +} + diff --git a/tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts b/tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts new file mode 100644 index 0000000000..7bec0c9fe0 --- /dev/null +++ b/tests/cases/compiler/readonlyAssignmentInSubclassOfClassExpression.ts @@ -0,0 +1,6 @@ +class C extends (class {} as new () => Readonly<{ attrib: number }>) { + constructor() { + super() + this.attrib = 2 + } +}