diff --git a/packages/eslint-plugin/docs/rules/class-methods-use-this.mdx b/packages/eslint-plugin/docs/rules/class-methods-use-this.mdx index 33f867fc7713..94138fc8aa24 100644 --- a/packages/eslint-plugin/docs/rules/class-methods-use-this.mdx +++ b/packages/eslint-plugin/docs/rules/class-methods-use-this.mdx @@ -9,7 +9,7 @@ import TabItem from '@theme/TabItem'; > > See **https://typescript-eslint.io/rules/class-methods-use-this** for documentation. -It adds support for ignoring `override` methods and/or methods on classes that implement an interface. +It adds support for ignoring `override` methods and/or methods on classes that implement an interface. It also supports auto-accessor properties. ## Options diff --git a/packages/eslint-plugin/src/rules/class-methods-use-this.ts b/packages/eslint-plugin/src/rules/class-methods-use-this.ts index 31f4539a1793..773a658ef133 100644 --- a/packages/eslint-plugin/src/rules/class-methods-use-this.ts +++ b/packages/eslint-plugin/src/rules/class-methods-use-this.ts @@ -104,14 +104,20 @@ export default createRule({ } | { class: TSESTree.ClassDeclaration | TSESTree.ClassExpression; - member: TSESTree.MethodDefinition | TSESTree.PropertyDefinition; + member: + | TSESTree.AccessorProperty + | TSESTree.MethodDefinition + | TSESTree.PropertyDefinition; parent: Stack | undefined; usesThis: boolean; }; let stack: Stack | undefined; function pushContext( - member?: TSESTree.MethodDefinition | TSESTree.PropertyDefinition, + member?: + | TSESTree.AccessorProperty + | TSESTree.MethodDefinition + | TSESTree.PropertyDefinition, ): void { if (member?.parent.type === AST_NODE_TYPES.ClassBody) { stack = { @@ -135,7 +141,8 @@ export default createRule({ ): void { if ( node.parent.type === AST_NODE_TYPES.MethodDefinition || - node.parent.type === AST_NODE_TYPES.PropertyDefinition + node.parent.type === AST_NODE_TYPES.PropertyDefinition || + node.parent.type === AST_NODE_TYPES.AccessorProperty ) { pushContext(node.parent); } else { @@ -172,7 +179,8 @@ export default createRule({ node.static || (node.type === AST_NODE_TYPES.MethodDefinition && node.kind === 'constructor') || - (node.type === AST_NODE_TYPES.PropertyDefinition && + ((node.type === AST_NODE_TYPES.PropertyDefinition || + node.type === AST_NODE_TYPES.AccessorProperty) && !enforceForClassFields) ) { return false; @@ -242,6 +250,16 @@ export default createRule({ }, ...(enforceForClassFields ? { + 'AccessorProperty > ArrowFunctionExpression.value'( + node: TSESTree.ArrowFunctionExpression, + ): void { + enterFunction(node); + }, + 'AccessorProperty > ArrowFunctionExpression.value:exit'( + node: TSESTree.ArrowFunctionExpression, + ): void { + exitFunction(node); + }, 'PropertyDefinition > ArrowFunctionExpression.value'( node: TSESTree.ArrowFunctionExpression, ): void { @@ -258,6 +276,12 @@ export default createRule({ /* * Class field value are implicit functions. */ + 'AccessorProperty:exit'(): void { + popContext(); + }, + 'AccessorProperty > *.key:exit'(): void { + pushContext(); + }, 'PropertyDefinition:exit'(): void { popContext(); }, diff --git a/packages/eslint-plugin/tests/rules/class-methods-use-this/class-methods-use-this.test.ts b/packages/eslint-plugin/tests/rules/class-methods-use-this/class-methods-use-this.test.ts index 76155119c5cc..495b14269ccc 100644 --- a/packages/eslint-plugin/tests/rules/class-methods-use-this/class-methods-use-this.test.ts +++ b/packages/eslint-plugin/tests/rules/class-methods-use-this/class-methods-use-this.test.ts @@ -47,6 +47,45 @@ class Foo { }, { code: ` +class Foo { + accessor method = () => {}; +} + `, + errors: [ + { + messageId: 'missingThis', + }, + ], + options: [{}], + }, + { + code: ` +class Foo { + private accessor method = () => {}; +} + `, + errors: [ + { + messageId: 'missingThis', + }, + ], + options: [{}], + }, + { + code: ` +class Foo { + protected accessor method = () => {}; +} + `, + errors: [ + { + messageId: 'missingThis', + }, + ], + options: [{}], + }, + { + code: ` class Foo { #method() {} } @@ -577,6 +616,14 @@ class Foo implements Bar { }, { code: ` +class Foo implements Bar { + accessor method = () => {}; +} + `, + options: [{ ignoreClassesThatImplementAnInterface: true }], + }, + { + code: ` class Foo implements Bar { get getter() {} } @@ -617,6 +664,14 @@ class Foo { }, { code: ` +class Foo { + override accessor method = () => {}; +} + `, + options: [{ ignoreOverrideMethods: true }], + }, + { + code: ` class Foo { override get getter(): number {} } @@ -901,5 +956,23 @@ class Foo implements Bar { }, ], }, + { + code: ` +class Foo { + accessor method = () => { + this; + }; +} + `, + }, + { + code: ` +class Foo { + accessor method = function () { + this; + }; +} + `, + }, ], });