diff --git a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts index baed3954060c..5d39c2a2610e 100644 --- a/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts +++ b/packages/eslint-plugin/tests/rules/no-unused-vars/no-unused-vars.test.ts @@ -1111,6 +1111,37 @@ foo &&= 2; let foo = 1; foo ||= 2; `, + ` +const foo = 1; +export = foo; + `, + ` +const Foo = 1; +interface Foo { + bar: string; +} +export = Foo; + `, + ` +interface Foo { + bar: string; +} +export = Foo; + `, + ` +type Foo = 1; +export = Foo; + `, + ` +type Foo = 1; +export = {} as Foo; + `, + ` +declare module 'foo' { + type Foo = 1; + export = Foo; +} + `, ], invalid: [ @@ -1874,5 +1905,47 @@ foo += 1; }, ], }, + { + code: ` +interface Foo { + bar: string; +} +type Bar = 1; +export = Bar; + `, + errors: [ + { + messageId: 'unusedVar', + line: 2, + column: 11, + data: { + varName: 'Foo', + action: 'defined', + additional: '', + }, + }, + ], + }, + { + code: ` +interface Foo { + bar: string; +} +type Bar = 1; +export = Foo; + `, + errors: [ + { + messageId: 'unusedVar', + line: 5, + column: 6, + data: { + varName: 'Bar', + action: 'defined', + additional: '', + }, + }, + ], + }, ], }); diff --git a/packages/scope-manager/src/referencer/ExportVisitor.ts b/packages/scope-manager/src/referencer/ExportVisitor.ts index 1af3a81ca2c6..24d35b49dab2 100644 --- a/packages/scope-manager/src/referencer/ExportVisitor.ts +++ b/packages/scope-manager/src/referencer/ExportVisitor.ts @@ -7,7 +7,8 @@ import { Visitor } from './Visitor'; type ExportNode = | TSESTree.ExportAllDeclaration | TSESTree.ExportDefaultDeclaration - | TSESTree.ExportNamedDeclaration; + | TSESTree.ExportNamedDeclaration + | TSESTree.TSExportAssignment; class ExportVisitor extends Visitor { readonly #referencer: Referencer; @@ -25,7 +26,10 @@ class ExportVisitor extends Visitor { } protected Identifier(node: TSESTree.Identifier): void { - if (this.#exportNode.exportKind === 'type') { + if ( + this.#exportNode.type !== AST_NODE_TYPES.TSExportAssignment && + this.#exportNode.exportKind === 'type' + ) { // export type { T }; // type exports can only reference types this.#referencer.currentScope().referenceType(node); @@ -49,6 +53,10 @@ class ExportVisitor extends Visitor { } } + protected TSExportAssignment(node: TSESTree.TSExportAssignment): void { + this.visit(node.expression); + } + protected ExportNamedDeclaration( node: TSESTree.ExportNamedDeclaration, ): void { diff --git a/packages/scope-manager/src/referencer/Referencer.ts b/packages/scope-manager/src/referencer/Referencer.ts index f5d36f2fa0ba..ddbdf7c61a4c 100644 --- a/packages/scope-manager/src/referencer/Referencer.ts +++ b/packages/scope-manager/src/referencer/Referencer.ts @@ -443,6 +443,10 @@ class Referencer extends Visitor { } } + protected TSExportAssignment(node: TSESTree.TSExportAssignment): void { + ExportVisitor.visit(this, node); + } + protected ExportNamedDeclaration( node: TSESTree.ExportNamedDeclaration, ): void { diff --git a/packages/scope-manager/tests/fixtures/export/equals1.ts.shot b/packages/scope-manager/tests/fixtures/export/equals1.ts.shot index 729abd96f92f..a4afe31abc8c 100644 --- a/packages/scope-manager/tests/fixtures/export/equals1.ts.shot +++ b/packages/scope-manager/tests/fixtures/export/equals1.ts.shot @@ -26,7 +26,7 @@ ScopeManager { Reference$2 { identifier: Identifier<"x">, isRead: true, - isTypeReference: false, + isTypeReference: true, isValueReference: true, isWrite: false, resolved: Variable$2, diff --git a/packages/scope-manager/tests/fixtures/export/equals3-type.ts b/packages/scope-manager/tests/fixtures/export/equals3-type.ts new file mode 100644 index 000000000000..a894a6341de0 --- /dev/null +++ b/packages/scope-manager/tests/fixtures/export/equals3-type.ts @@ -0,0 +1,4 @@ +interface Foo { + bar: 1; +} +export = Foo; diff --git a/packages/scope-manager/tests/fixtures/export/equals3-type.ts.shot b/packages/scope-manager/tests/fixtures/export/equals3-type.ts.shot new file mode 100644 index 000000000000..49ebdfb950af --- /dev/null +++ b/packages/scope-manager/tests/fixtures/export/equals3-type.ts.shot @@ -0,0 +1,49 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`export equals3-type 1`] = ` +ScopeManager { + variables: [ + ImplicitGlobalConstTypeVariable, + Variable$2 { + defs: [ + TypeDefinition$1 { + name: Identifier<"Foo">, + node: TSInterfaceDeclaration$1, + }, + ], + name: "Foo", + references: [ + Reference$1 { + identifier: Identifier<"Foo">, + isRead: true, + isTypeReference: true, + isValueReference: true, + isWrite: false, + resolved: Variable$2, + }, + ], + isValueVariable: false, + isTypeVariable: true, + }, + ], + scopes: [ + GlobalScope$1 { + block: Program$2, + isStrict: false, + references: [ + Reference$1, + ], + set: Map { + "const" => ImplicitGlobalConstTypeVariable, + "Foo" => Variable$2, + }, + type: "global", + upper: null, + variables: [ + ImplicitGlobalConstTypeVariable, + Variable$2, + ], + }, + ], +} +`;