From 395220691676af1d15e86520ec935c22e8640493 Mon Sep 17 00:00:00 2001 From: Tim Kraut Date: Tue, 5 Feb 2019 14:37:45 +0100 Subject: [PATCH] feat(no-empty-interface): add allowSingleExtend option --- .../docs/rules/no-empty-interface.md | 17 ++++++++ .../src/rules/no-empty-interface.ts | 43 +++++++++++++++---- .../tests/rules/no-empty-interface.test.ts | 13 +++++- 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/packages/eslint-plugin/docs/rules/no-empty-interface.md b/packages/eslint-plugin/docs/rules/no-empty-interface.md index a300c81b1041..37aa7e4dbc11 100644 --- a/packages/eslint-plugin/docs/rules/no-empty-interface.md +++ b/packages/eslint-plugin/docs/rules/no-empty-interface.md @@ -38,6 +38,23 @@ interface Bar { interface Baz extends Foo, Bar {} ``` +### Options + +This rule accepts a single object option with the following default configuration: + +```json +{ + "@typescript-eslint/no-empty-interface": [ + "error", + { + "allowSingleExtends": false + } + ] +} +``` + +- `allowSingleExtends: true` will silence warnings about extending a single interface without adding additional members + ## When Not To Use It If you don't care about having empty/meaningless interfaces, then you will not need this rule. diff --git a/packages/eslint-plugin/src/rules/no-empty-interface.ts b/packages/eslint-plugin/src/rules/no-empty-interface.ts index 52e1d0ddf9ab..f4373a89375e 100644 --- a/packages/eslint-plugin/src/rules/no-empty-interface.ts +++ b/packages/eslint-plugin/src/rules/no-empty-interface.ts @@ -6,7 +6,14 @@ import { TSESTree } from '@typescript-eslint/typescript-estree'; import * as util from '../util'; -export default util.createRule({ +type Options = [ + { + allowSingleExtends?: boolean; + } +]; +type MessageIds = 'noEmpty' | 'noEmptyWithSuper'; + +export default util.createRule({ name: 'no-empty-interface', meta: { type: 'suggestion', @@ -21,13 +28,28 @@ export default util.createRule({ noEmptyWithSuper: 'An interface declaring no members is equivalent to its supertype.' }, - schema: [] + schema: [ + { + type: 'object', + additionalProperties: false, + properties: { + allowSingleExtends: { + type: 'boolean' + } + } + } + ] }, - defaultOptions: [], - create(context) { + defaultOptions: [ + { + allowSingleExtends: false + } + ], + create(context, [{ allowSingleExtends }]) { return { TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration) { if (node.body.body.length !== 0) { + // interface contains members --> Nothing to report return; } @@ -37,10 +59,15 @@ export default util.createRule({ messageId: 'noEmpty' }); } else if (node.extends.length === 1) { - context.report({ - node: node.id, - messageId: 'noEmptyWithSuper' - }); + // interface extends exactly 1 interface --> Report depending on rule setting + if (allowSingleExtends) { + return; + } else { + context.report({ + node: node.id, + messageId: 'noEmptyWithSuper' + }); + } } } }; 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 2410509a1fcd..fb7b95009129 100644 --- a/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts +++ b/packages/eslint-plugin/tests/rules/no-empty-interface.test.ts @@ -23,7 +23,17 @@ interface Bar { // valid because extending multiple interfaces can be used instead of a union type interface Baz extends Foo, Bar {} - ` + `, + { + code: ` +interface Foo { + name: string; +} + +interface Bar extends Foo {} + `, + options: [{ allowSingleExtends: true }] + } ], invalid: [ { @@ -54,6 +64,7 @@ interface Foo { interface Bar extends Foo {} `, + options: [{ allowSingleExtends: false }], errors: [ { messageId: 'noEmptyWithSuper', 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