Skip to content

Commit

Permalink
fix(eslint-plugin): [no-empty-interface] use suggestion fixer for amb…
Browse files Browse the repository at this point in the history
…ient contexts (#1880)
  • Loading branch information
vapurrmaid authored Apr 12, 2020
1 parent fd75424 commit 62b2278
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 12 deletions.
54 changes: 42 additions & 12 deletions packages/eslint-plugin/src/rules/no-empty-interface.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import * as util from '../util';
import {
AST_NODE_TYPES,
TSESLint,
} from '@typescript-eslint/experimental-utils';

type Options = [
{
Expand Down Expand Up @@ -43,6 +47,7 @@ export default util.createRule<Options, MessageIds>({
return {
TSInterfaceDeclaration(node): void {
const sourceCode = context.getSourceCode();
const filename = context.getFilename();

if (node.body.body.length !== 0) {
// interface contains members --> Nothing to report
Expand All @@ -58,21 +63,46 @@ export default util.createRule<Options, MessageIds>({
} 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,
},
],
}),
});
}
}
Expand Down
36 changes: 36 additions & 0 deletions packages/eslint-plugin/tests/rules/no-empty-interface.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -148,5 +148,41 @@ type Foo<T> = Bar<T>
},
],
},
{
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(),
},
],
});

0 comments on commit 62b2278

Please sign in to comment.