Skip to content

Commit c71f423

Browse files
authored
fix(eslint-plugin): [no-duplicate-imports] distinguish member, default (typescript-eslint#2637)
1 parent daac9da commit c71f423

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

packages/eslint-plugin/src/rules/no-duplicate-imports.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ export default util.createRule<Options, MessageIds>({
3535
create(context, [option]) {
3636
const rules = baseRule.create(context);
3737
const includeExports = option.includeExports;
38-
const typeImports = new Set();
38+
const typeMemberImports = new Set();
39+
const typeDefaultImports = new Set();
3940
const typeExports = new Set();
4041

4142
function report(
@@ -62,16 +63,32 @@ export default util.createRule<Options, MessageIds>({
6263
);
6364
}
6465

66+
function isAllMemberImport(node: TSESTree.ImportDeclaration): boolean {
67+
return node.specifiers.every(
68+
specifier => specifier.type === AST_NODE_TYPES.ImportSpecifier,
69+
);
70+
}
71+
6572
function checkTypeImport(node: TSESTree.ImportDeclaration): void {
6673
if (isStringLiteral(node.source)) {
6774
const value = node.source.value;
68-
if (typeImports.has(value)) {
75+
const isMemberImport = isAllMemberImport(node);
76+
if (
77+
isMemberImport
78+
? typeMemberImports.has(value)
79+
: typeDefaultImports.has(value)
80+
) {
6981
report('importType', node, value);
7082
}
83+
7184
if (includeExports && typeExports.has(value)) {
7285
report('importTypeAs', node, value);
7386
}
74-
typeImports.add(value);
87+
if (isMemberImport) {
88+
typeMemberImports.add(value);
89+
} else {
90+
typeDefaultImports.add(value);
91+
}
7592
}
7693
}
7794

@@ -83,7 +100,7 @@ export default util.createRule<Options, MessageIds>({
83100
if (typeExports.has(value)) {
84101
report('exportType', node, value);
85102
}
86-
if (typeImports.has(value)) {
103+
if (typeMemberImports.has(value) || typeDefaultImports.has(value)) {
87104
report('exportTypeAs', node, value);
88105
}
89106
typeExports.add(value);

packages/eslint-plugin/tests/rules/no-duplicate-imports.test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,32 @@ const ruleTester = new RuleTester({
55
parser: '@typescript-eslint/parser',
66
});
77

8-
ruleTester.run('no-dupe-class-members', rule, {
8+
ruleTester.run('no-duplicate-imports', rule, {
99
valid: [
1010
{
1111
code: "import type foo from 'foo';",
1212
},
1313
{
1414
code: "import type { foo } from 'foo';",
1515
},
16+
{
17+
code: `
18+
import type { foo } from 'foo';
19+
import type Bar from 'foo';
20+
`,
21+
},
22+
{
23+
code: `
24+
import type Foo from 'foo';
25+
import type { bar } from 'foo';
26+
`,
27+
},
28+
{
29+
code: `
30+
import type Foo from 'foo';
31+
import type { bar as Bar } from 'foo';
32+
`,
33+
},
1634
{
1735
code: `
1836
import foo from 'foo';
@@ -69,6 +87,14 @@ ruleTester.run('no-dupe-class-members', rule, {
6987
`,
7088
options: [{ includeExports: true }],
7189
},
90+
{
91+
code: `
92+
import type Foo from 'foo';
93+
import type { bar } from 'foo';
94+
export type { bar };
95+
`,
96+
options: [{ includeExports: true }],
97+
},
7298
],
7399
invalid: [
74100
{
@@ -116,6 +142,15 @@ ruleTester.run('no-dupe-class-members', rule, {
116142
options: [{ includeExports: true }],
117143
errors: [{ messageId: 'exportTypeAs' }],
118144
},
145+
{
146+
code: `
147+
import type Foo from 'foo';
148+
import type { bar } from 'foo';
149+
export type { bar } from 'foo';
150+
`,
151+
options: [{ includeExports: true }],
152+
errors: [{ messageId: 'exportTypeAs' }],
153+
},
119154
{
120155
code: `
121156
export type * as foo from 'foo';

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