diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index 2e9e61c1e0ef..d279e9bd4f61 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -1,4 +1,8 @@ import * as util from '../util'; +import { + AST_NODE_TYPES, + TSESLint, +} from '@typescript-eslint/experimental-utils'; type Options = [ { @@ -43,6 +47,7 @@ export default util.createRule({ return { TSInterfaceDeclaration(node): void { const sourceCode = context.getSourceCode(); + const filename = context.getFilename(); if (node.body.body.length !== 0) { // interface contains members --> Nothing to report @@ -58,21 +63,46 @@ export default util.createRule({ } else if (extend.length === 1) { // interface extends exactly 1 interface --> Report depending on rule setting if (!allowSingleExtends) { + const fix = (fixer: TSESLint.RuleFixer): TSESLint.RuleFix => { + let typeParam = ''; + if (node.typeParameters) { + typeParam = sourceCode.getText(node.typeParameters); + } + return fixer.replaceText( + node, + `type ${sourceCode.getText( + node.id, + )}${typeParam} = ${sourceCode.getText(extend[0])}`, + ); + }; + + // Check if interface is within ambient declaration + let useAutoFix = true; + if (util.isDefinitionFile(filename)) { + const scope = context.getScope(); + if ( + scope.block.parent && + scope.block.parent.type === + AST_NODE_TYPES.TSModuleDeclaration && + scope.block.parent.declare + ) { + useAutoFix = false; + } + } + context.report({ node: node.id, messageId: 'noEmptyWithSuper', - fix: fixer => { - let typeParam = ''; - if (node.typeParameters) { - typeParam = sourceCode.getText(node.typeParameters); - } - return fixer.replaceText( - node, - `type ${sourceCode.getText( - node.id, - )}${typeParam} = ${sourceCode.getText(extend[0])}`, - ); - }, + ...(useAutoFix + ? { fix } + : { + suggest: [ + { + messageId: 'noEmptyWithSuper', + fix, + }, + ], + }), }); } } diff --git a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts index 840e729f183d..d0281ec77a03 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts @@ -148,5 +148,41 @@ type Foo = Bar }, ], }, + { + filename: 'test.d.ts', + code: ` +declare module FooBar { + type Baz = typeof baz; + export interface Bar extends Baz {} +} + `.trimRight(), + errors: [ + { + messageId: 'noEmptyWithSuper', + line: 4, + column: 20, + endLine: 4, + endColumn: 23, + suggestions: [ + { + messageId: 'noEmptyWithSuper', + output: noFormat` +declare module FooBar { + type Baz = typeof baz; + export type Bar = Baz +} + `.trimRight(), + }, + ], + }, + ], + // output matches input because a suggestion was made + output: ` +declare module FooBar { + type Baz = typeof baz; + export interface Bar extends Baz {} +} + `.trimRight(), + }, ], }); pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy