Skip to content

Commit bf46f8c

Browse files
timkrautbradzacher
authored andcommitted
feat(no-empty-interface): add allowSingleExtend option (typescript-eslint#215)
1 parent 2a4aaaa commit bf46f8c

File tree

3 files changed

+64
-9
lines changed

3 files changed

+64
-9
lines changed

packages/eslint-plugin/docs/rules/no-empty-interface.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,23 @@ interface Bar {
3838
interface Baz extends Foo, Bar {}
3939
```
4040

41+
### Options
42+
43+
This rule accepts a single object option with the following default configuration:
44+
45+
```json
46+
{
47+
"@typescript-eslint/no-empty-interface": [
48+
"error",
49+
{
50+
"allowSingleExtends": false
51+
}
52+
]
53+
}
54+
```
55+
56+
- `allowSingleExtends: true` will silence warnings about extending a single interface without adding additional members
57+
4158
## When Not To Use It
4259

4360
If you don't care about having empty/meaningless interfaces, then you will not need this rule.

packages/eslint-plugin/src/rules/no-empty-interface.ts

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@
66
import { TSESTree } from '@typescript-eslint/typescript-estree';
77
import * as util from '../util';
88

9-
export default util.createRule({
9+
type Options = [
10+
{
11+
allowSingleExtends?: boolean;
12+
}
13+
];
14+
type MessageIds = 'noEmpty' | 'noEmptyWithSuper';
15+
16+
export default util.createRule<Options, MessageIds>({
1017
name: 'no-empty-interface',
1118
meta: {
1219
type: 'suggestion',
@@ -21,13 +28,28 @@ export default util.createRule({
2128
noEmptyWithSuper:
2229
'An interface declaring no members is equivalent to its supertype.'
2330
},
24-
schema: []
31+
schema: [
32+
{
33+
type: 'object',
34+
additionalProperties: false,
35+
properties: {
36+
allowSingleExtends: {
37+
type: 'boolean'
38+
}
39+
}
40+
}
41+
]
2542
},
26-
defaultOptions: [],
27-
create(context) {
43+
defaultOptions: [
44+
{
45+
allowSingleExtends: false
46+
}
47+
],
48+
create(context, [{ allowSingleExtends }]) {
2849
return {
2950
TSInterfaceDeclaration(node: TSESTree.TSInterfaceDeclaration) {
3051
if (node.body.body.length !== 0) {
52+
// interface contains members --> Nothing to report
3153
return;
3254
}
3355

@@ -37,10 +59,15 @@ export default util.createRule({
3759
messageId: 'noEmpty'
3860
});
3961
} else if (node.extends.length === 1) {
40-
context.report({
41-
node: node.id,
42-
messageId: 'noEmptyWithSuper'
43-
});
62+
// interface extends exactly 1 interface --> Report depending on rule setting
63+
if (allowSingleExtends) {
64+
return;
65+
} else {
66+
context.report({
67+
node: node.id,
68+
messageId: 'noEmptyWithSuper'
69+
});
70+
}
4471
}
4572
}
4673
};

packages/eslint-plugin/tests/rules/no-empty-interface.test.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,17 @@ interface Bar {
2323
2424
// valid because extending multiple interfaces can be used instead of a union type
2525
interface Baz extends Foo, Bar {}
26-
`
26+
`,
27+
{
28+
code: `
29+
interface Foo {
30+
name: string;
31+
}
32+
33+
interface Bar extends Foo {}
34+
`,
35+
options: [{ allowSingleExtends: true }]
36+
}
2737
],
2838
invalid: [
2939
{
@@ -54,6 +64,7 @@ interface Foo {
5464
5565
interface Bar extends Foo {}
5666
`,
67+
options: [{ allowSingleExtends: false }],
5768
errors: [
5869
{
5970
messageId: 'noEmptyWithSuper',

0 commit comments

Comments
 (0)
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