8000 fix(eslint-plugin): [consistent-type-definitions] remove fixer when t… · dopecodez/typescript-eslint@2326238 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2326238

Browse files
author
Daniil Dubrava
authored
fix(eslint-plugin): [consistent-type-definitions] remove fixer when the interface is within a global module declaration (typescript-eslint#2739)
1 parent 9441d50 commit 2326238

File tree

2 files changed

+132
-23
lines changed

2 files changed

+132
-23
lines changed

packages/eslint-plugin/src/rules/consistent-type-definitions.ts

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import {
2+
AST_NODE_TYPES,
23
AST_TOKEN_TYPES,
34
TSESLint,
45
TSESTree,
@@ -31,6 +32,21 @@ export default util.createRule({
3132
create(context, [option]) {
3233
const sourceCode = context.getSourceCode();
3334

35+
/**
36+
* Iterates from the highest parent to the currently traversed node
37+
* to determine whether any node in tree is globally declared module declaration
38+
*/
39+
function isCurrentlyTraversedNodeWithinModuleDeclaration(): boolean {
40+
return context
41+
.getAncestors()
42+
.some(
43+
node =>
44+
node.type === AST_NODE_TYPES.TSModuleDeclaration &&
45+
node.declare &&
46+
node.global,
47+
);
48+
}
49+
3450
return {
3551
"TSTypeAliasDeclaration[typeAnnotation.type='TSTypeLiteral']"(
3652
node: TSESTree.TSTypeAliasDeclaration,
@@ -73,32 +89,41 @@ export default util.createRule({
7389
context.report({
7490
node: node.id,
7591
messageId: 'typeOverInterface',
76-
fix(fixer) {
77-
const typeNode = node.typeParameters ?? node.id;
78-
const fixes: TSESLint.RuleFix[] = [];
92+
/**
93+
* remove automatically fix when the interface is within a declare global
94+
* @see {@link https://github.com/typescript-eslint/typescript-eslint/issues/2707}
95+
*/
96+
fix: isCurrentlyTraversedNodeWithinModuleDeclaration()
97+
? null
98+
: (fixer): TSESLint.RuleFix[] => {
99+
const typeNode = node.typeParameters ?? node.id;
100+
const fixes: TSESLint.RuleFix[] = [];
79101

80-
const firstToken = sourceCode.getFirstToken(node);
81-
if (firstToken) {
82-
fixes.push(fixer.replaceText(firstToken, 'type'));
83-
fixes.push(
84-
fixer.replaceTextRange(
85-
[typeNode.range[1], node.body.range[0]],
86-
' = ',
87-
),
88-
);
89-
}
102+
const firstToken = sourceCode.getFirstToken(node);
103+
if (firstToken) {
104+
fixes.push(fixer.replaceText(firstToken, 'type'));
105+
fixes.push(
106+
fixer.replaceTextRange(
107+
[typeNode.range[1], node.body.range[0]],
108+
' = ',
109+
),
110+
);
111+
}
90112

91-
if (node.extends) {
92-
node.extends.forEach(heritage => {
93-
const typeIdentifier = sourceCode.getText(heritage);
94-
fixes.push(
95-
fixer.insertTextAfter(node.body, ` & ${typeIdentifier}`),
96-
);
97-
});
98-
}
113+
if (node.extends) {
114+
node.extends.forEach(heritage => {
115+
const typeIdentifier = sourceCode.getText(heritage);
116+
fixes.push(
117+
fixer.insertTextAfter(
118+
node.body,
119+
` & ${typeIdentifier}`,
120+
),
121+
);
122+
});
123+
}
99124

100-
return fixes;
101-
},
125+
return fixes;
126+
},
102127
});
103128
}
104129
},

packages/eslint-plugin/tests/rules/consistent-type-definitions.test.ts

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,5 +197,89 @@ export type W<T> = {
197197
},
198198
],
199199
},
200+
{
201+
code: `
202+
namespace JSX {
203+
interface Array<T> {
204+
foo(x: (x: number) => T): T[];
205+
}
206+
}
207+
`,
208+
output: noFormat`
209+
namespace JSX {
210+
type Array<T> = {
211+
foo(x: (x: number) => T): T[];
212+
}
213+
}
214+
`,
215+
options: ['type'],
216+
errors: [
217+
{
218+
messageId: 'typeOverInterface',
219+
line: 3,
220+
column: 13,
221+
},
222+
],
223+
},
224+
{
225+
code: `
226+
global {
227+
interface Array<T> {
228+
foo(x: (x: number) => T): T[];
229+
}
230+
}
231+
`,
232+
output: noFormat`
233+
global {
234+
type Array<T> = {
235+
foo(x: (x: number) => T): T[];
236+
}
237+
}
238+
`,
239+
options: ['type'],
240+
errors: [
241+
{
242+
messageId: 'typeOverInterface',
243+
line: 3,
244+
column: 13,
245+
},
246+
],
247+
},
248+
{
249+
code: `
250+
declare global {
251+
interface Array<T> {
252+
foo(x: (x: number) => T): T[];
253+
}
254+
}
255+
`,
256+
output: null,
257+
options: ['type'],
258+
errors: [
259+
{
260+
messageId: 'typeOverInterface',
261+
line: 3,
262+
column: 13,
263+
},
264+
],
265+
},
266+
{
267+
code: `
268+
declare global {
269+
namespace Foo {
270+
interface Bar {}
271+
}
272+
}
273+
`,
274+
output: null,
275+
options: ['type'],
276+
errors: [
277+
{
278+
messageId: 'typeOverInterface',
279+
line: 4,
280+
column: 15,
281+
},
282+
],
283+
},
200284
],
201285
});

0 commit comments

Comments
 (0)
0