diff --git a/packages/eslint-plugin/src/rules/prefer-readonly.ts b/packages/eslint-plugin/src/rules/prefer-readonly.ts index 3a1cd3f42f6..3a9e6cdca66 100644 --- a/packages/eslint-plugin/src/rules/prefer-readonly.ts +++ b/packages/eslint-plugin/src/rules/prefer-readonly.ts @@ -119,7 +119,10 @@ export default util.createRule({ ts.isArrayLiteralExpression(parent.parent)) ) { current = parent; - } else if (ts.isBinaryExpression(parent)) { + } else if ( + ts.isBinaryExpression(parent) && + !ts.isPropertyAccessExpression(current) + ) { return ( parent.left === current && parent.operatorToken.kind === ts.SyntaxKind.EqualsToken diff --git a/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts b/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts index 333ffc9b5ff..10f2e3d1e07 100644 --- a/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts +++ b/packages/eslint-plugin/tests/rules/prefer-readonly.test.ts @@ -339,6 +339,34 @@ class Foo { } `, }, + { + code: ` + class Test { + private testObj = { + prop: '', + }; + + public test(): void { + this.testObj = ''; + } + } + `, + }, + { + code: ` + class TestObject { + public prop: number; + } + + class Test { + private testObj = new TestObject(); + + public test(): void { + this.testObj = new TestObject(); + } + } + `, + }, ], invalid: [ { @@ -742,5 +770,322 @@ function ClassWithName {}>(Base: TBase) { }, ], }, + { + code: ` + class Test { + private testObj = { + prop: '', + }; + + public test(): void { + this.testObj.prop = ''; + } + } + `, + output: ` + class Test { + private readonly testObj = { + prop: '', + }; + + public test(): void { + this.testObj.prop = ''; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class TestObject { + public prop: number; + } + + class Test { + private testObj = new TestObject(); + + public test(): void { + this.testObj.prop = 10; + } + } + `, + output: ` + class TestObject { + public prop: number; + } + + class Test { + private readonly testObj = new TestObject(); + + public test(): void { + this.testObj.prop = 10; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 7, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class Test { + private testObj = { + prop: '', + }; + public test(): void { + this.testObj.prop; + } + } + `, + output: ` + class Test { + private readonly testObj = { + prop: '', + }; + public test(): void { + this.testObj.prop; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class Test { + private testObj = {}; + public test(): void { + this.testObj?.prop; + } + } + `, + output: ` + class Test { + private readonly testObj = {}; + public test(): void { + this.testObj?.prop; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class Test { + private testObj = {}; + public test(): void { + this.testObj!.prop; + } + } + `, + output: ` + class Test { + private readonly testObj = {}; + public test(): void { + this.testObj!.prop; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class Test { + private testObj = {}; + public test(): void { + this.testObj.prop.prop = ''; + } + } + `, + output: ` + class Test { + private readonly testObj = {}; + public test(): void { + this.testObj.prop.prop = ''; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class Test { + private testObj = {}; + public test(): void { + this.testObj.prop.doesSomething(); + } + } + `, + output: ` + class Test { + private readonly testObj = {}; + public test(): void { + this.testObj.prop.doesSomething(); + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class Test { + private testObj = {}; + public test(): void { + this.testObj?.prop.prop; + } + } + `, + output: ` + class Test { + private readonly testObj = {}; + public test(): void { + this.testObj?.prop.prop; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class Test { + private testObj = {}; + public test(): void { + this.testObj?.prop?.prop; + } + } + `, + output: ` + class Test { + private readonly testObj = {}; + public test(): void { + this.testObj?.prop?.prop; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class Test { + private testObj = {}; + public test(): void { + this.testObj.prop?.prop; + } + } + `, + output: ` + class Test { + private readonly testObj = {}; + public test(): void { + this.testObj.prop?.prop; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, + { + code: ` + class Test { + private testObj = {}; + public test(): void { + this.testObj!.prop?.prop; + } + } + `, + output: ` + class Test { + private readonly testObj = {}; + public test(): void { + this.testObj!.prop?.prop; + } + } + `, + errors: [ + { + data: { + name: 'testObj', + }, + line: 3, + messageId: 'preferReadonly', + }, + ], + }, ], });