diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts index 166022cee20..323d85b94a6 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars.test.ts @@ -757,6 +757,14 @@ export default function (@Optional() value = []) { function Optional() { return () => {}; +} + `, + // https://github.com/typescript-eslint/typescript-eslint/issues/2417 + ` +import { FooType } from './fileA'; + +export abstract class Foo { + protected abstract readonly type: FooType; } `, ], diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index 302dda1c457..1b71d7d0c50 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -139,6 +139,13 @@ class Referencer extends Visitor { this.close(node); } + protected visitClassProperty( + node: TSESTree.TSAbstractClassProperty | TSESTree.ClassProperty, + ): void { + this.visitProperty(node); + this.visitType(node.typeAnnotation); + } + protected visitForIn( node: TSESTree.ForInStatement | TSESTree.ForOfStatement, ): void { @@ -413,8 +420,7 @@ class Referencer extends Visitor { } protected ClassProperty(node: TSESTree.ClassProperty): void { - this.visitProperty(node); - this.visitType(node.typeAnnotation); + this.visitClassProperty(node); } protected ContinueStatement(): void { @@ -562,7 +568,7 @@ class Referencer extends Visitor { protected TSAbstractClassProperty( node: TSESTree.TSAbstractClassProperty, ): void { - this.visitProperty(node); + this.visitClassProperty(node); } protected TSAbstractMethodDefinition( diff --git a/packages/scope-manager/tests/fixtures/class/declaration/abstract-property.ts b/packages/scope-manager/tests/fixtures/class/declaration/abstract-property.ts new file mode 100644 index 00000000000..9b4a5e38adf --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/declaration/abstract-property.ts @@ -0,0 +1,5 @@ +type T = 1; + +abstract class Foo { + protected abstract readonly prop: T; +} diff --git a/packages/scope-manager/tests/fixtures/class/declaration/abstract-property.ts.shot b/packages/scope-manager/tests/fixtures/class/declaration/abstract-property.ts.shot new file mode 100644 index 00000000000..75750d50fbd --- /dev/null +++ b/packages/scope-manager/tests/fixtures/class/declaration/abstract-property.ts.shot @@ -0,0 +1,85 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`class declaration abstract-property 1`] = ` +ScopeManager { + variables: Array [ + Variable$1 { + defs: Array [ + TypeDefinition$1 { + name: Identifier<"T">, + node: TSTypeAliasDeclaration$1, + }, + ], + name: "T", + references: Array [ + Reference$1 { + identifier: Identifier<"T">, + isRead: true, + isTypeReference: true, + isValueReference: false, + isWrite: false, + resolved: Variable$1, + }, + ], + isValueVariable: false, + isTypeVariable: true, + }, + Variable$2 { + defs: Array [ + ClassNameDefinition$2 { + name: Identifier<"Foo">, + node: ClassDeclaration$2, + }, + ], + name: "Foo", + references: Array [], + isValueVariable: true, + isTypeVariable: true, + }, + Variable$3 { + defs: Array [ + ClassNameDefinition$3 { + name: Identifier<"Foo">, + node: ClassDeclaration$2, + }, + ], + name: "Foo", + references: Array [], + isValueVariable: true, + isTypeVariable: true, + }, + ], + scopes: Array [ + GlobalScope$1 { + block: Program$3, + isStrict: false, + references: Array [], + set: Map { + "T" => Variable$1, + "Foo" => Variable$2, + }, + type: "global", + upper: null, + variables: Array [ + Variable$1, + Variable$2, + ], + }, + ClassScope$2 { + block: ClassDeclaration$2, + isStrict: true, + references: Array [ + Reference$1, + ], + set: Map { + "Foo" => Variable$3, + }, + type: "class", + upper: GlobalScope$1, + variables: Array [ + Variable$3, + ], + }, + ], +} +`;