From e6b30a42d3e82bda96929dce56d6d174b4e27e01 Mon Sep 17 00:00:00 2001 From: Joshua Chen Date: Mon, 2 Oct 2023 12:54:39 -0400 Subject: [PATCH] fix(eslint-plugin): [no-useless-empty-export] exempt .d.ts --- .../src/rules/no-useless-empty-export.ts | 28 +++++++------ .../rules/no-useless-empty-export.test.ts | 42 +++++++++++++++++++ 2 files changed, 58 insertions(+), 12 deletions(-) diff --git a/packages/eslint-plugin/src/rules/no-useless-empty-export.ts b/packages/eslint-plugin/src/rules/no-useless-empty-export.ts index 7c2b8ca3ea22..2c32769c10b6 100644 --- a/packages/eslint-plugin/src/rules/no-useless-empty-export.ts +++ b/packages/eslint-plugin/src/rules/no-useless-empty-export.ts @@ -40,6 +40,12 @@ export default util.createRule({ }, defaultOptions: [], create(context) { + // In a definition file, export {} is necessary to make the module properly + // encapsulated, even when there are other exports + // https://github.com/typescript-eslint/typescript-eslint/issues/4975 + if (util.isDefinitionFile(context.getFilename())) { + return {}; + } function checkNode( node: TSESTree.Program | TSESTree.TSModuleDeclaration, ): void { @@ -47,27 +53,25 @@ export default util.createRule({ return; } - let emptyExport: TSESTree.ExportNamedDeclaration | undefined; + const emptyExports: TSESTree.ExportNamedDeclaration[] = []; let foundOtherExport = false; for (const statement of node.body) { if (isEmptyExport(statement)) { - emptyExport = statement; - - if (foundOtherExport) { - break; - } + emptyExports.push(statement); } else if (exportOrImportNodeTypes.has(statement.type)) { foundOtherExport = true; } } - if (emptyExport && foundOtherExport) { - context.report({ - fix: fixer => fixer.remove(emptyExport!), - messageId: 'uselessExport', - node: emptyExport, - }); + if (foundOtherExport) { + for (const emptyExport of emptyExports) { + context.report({ + fix: fixer => fixer.remove(emptyExport), + messageId: 'uselessExport', + node: emptyExport, + }); + } } } diff --git a/packages/eslint-plugin/tests/rules/no-useless-empty-export.test.ts b/packages/eslint-plugin/tests/rules/no-useless-empty-export.test.ts index 6ed201033bb4..caef56622cbc 100644 --- a/packages/eslint-plugin/tests/rules/no-useless-empty-export.test.ts +++ b/packages/eslint-plugin/tests/rules/no-useless-empty-export.test.ts @@ -37,6 +37,35 @@ ruleTester.run('no-useless-empty-export', rule, { ` export {}; `, + // https://github.com/microsoft/TypeScript/issues/38592 + { + code: ` + export type A = 1; + export {}; + `, + filename: 'foo.d.ts', + }, + { + code: ` + export declare const a = 2; + export {}; + `, + filename: 'foo.d.ts', + }, + { + code: ` + import type { A } from '_'; + export {}; + `, + filename: 'foo.d.ts', + }, + { + code: ` + import { A } from '_'; + export {}; + `, + filename: 'foo.d.ts', + }, ], invalid: [ { @@ -120,6 +149,19 @@ export {}; output: ` import _ = require('_'); + `, + }, + { + code: ` +import _ = require('_'); +export {}; +export {}; + `, + errors: [error, error], + output: ` +import _ = require('_'); + + `, }, ],