Skip to content

Commit 712ee49

Browse files
nwalters512GoodForOneFare
authored andcommittedAug 17, 2021
[fix] no-duplicates: correctly handle case of mixed default/named type imports
Co-authored-by: Nathan Walters <nwalters@nerdwallet.com> Co-authored-by: Gord Pearson <gord.pearson@shopify.com>
1 parent 3977c42 commit 712ee49

File tree

3 files changed

+85
-8
lines changed

3 files changed

+85
-8
lines changed
 

‎CHANGELOG.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
99
### Fixed
1010
- `ExportMap`: Add default export when esModuleInterop is true and anything is exported ([#2184], thanks [@Maxim-Mazurok])
1111
- [`named`], [`namespace`]: properly set reexports on `export * as … from` ([#1998], [#2161], thanks [@ljharb])
12+
- [`no-duplicates`]: correctly handle case of mixed default/named type imports ([#2149], thanks [@GoodForOneFare], [@nwalters512])
1213

1314
### Changed
1415
- [Docs] `max-dependencies`: 📖 Document `ignoreTypeImports` option ([#2196], thanks [@himynameisdave])
@@ -897,6 +898,7 @@ for info on changes for earlier releases.
897898
[#2160]: https://github.com/import-js/eslint-plugin-import/pull/2160
898899
[#2158]: https://github.com/import-js/eslint-plugin-import/pull/2158
899900
[#2156]: https://github.com/import-js/eslint-plugin-import/pull/2156
901+
[#2149]: https://github.com/benmosher/eslint-plugin-import/pull/2149
900902
[#2146]: https://github.com/import-js/eslint-plugin-import/pull/2146
901903
[#2140]: https://github.com/import-js/eslint-plugin-import/pull/2140
902904
[#2138]: https://github.com/import-js/eslint-plugin-import/pull/2138
@@ -1404,6 +1406,7 @@ for info on changes for earlier releases.
14041406
[@gavriguy]: https://github.com/gavriguy
14051407
[@giodamelio]: https://github.com/giodamelio
14061408
[@golopot]: https://github.com/golopot
1409+
[@GoodForOneFare]: https://github.com/GoodForOneFare
14071410
[@graingert]: https://github.com/graingert
14081411
[@grit96]: https://github.com/grit96
14091412
[@guillaumewuip]: https://github.com/guillaumewuip
@@ -1471,6 +1474,7 @@ for info on changes for earlier releases.
14711474
[@nicolashenry]: https://github.com/nicolashenry
14721475
[@noelebrun]: https://github.com/noelebrun
14731476
[@ntdb]: https://github.com/ntdb
1477+
[@nwalters512]: https://github.com/nwalters512
14741478
[@panrafal]: https://github.com/panrafal
14751479
[@paztis]: https://github.com/paztis
14761480
[@pcorpet]: https://github.com/pcorpet
@@ -1533,4 +1537,4 @@ for info on changes for earlier releases.
15331537
[@wtgtybhertgeghgtwtg]: https://github.com/wtgtybhertgeghgtwtg
15341538
[@xpl]: https://github.com/xpl
15351539
[@yordis]: https://github.com/yordis
1536-
[@zloirock]: https://github.com/zloirock
1540+
[@zloirock]: https://github.com/zloirock

‎src/rules/no-duplicates.js

+16-6
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,22 @@ module.exports = {
276276

277277
const imported = new Map();
278278
const nsImported = new Map();
279-
const typesImported = new Map();
279+
const defaultTypesImported = new Map();
280+
const namedTypesImported = new Map();
281+
282+
function getImportMap(n) {
283+
if (n.importKind === 'type') {
284+
return n.specifiers[0].type === 'ImportDefaultSpecifier' ? defaultTypesImported : namedTypesImported;
285+
}
286+
287+
return hasNamespace(n) ? nsImported : imported;
288+
}
289+
280290
return {
281-
'ImportDeclaration': function (n) {
291+
ImportDeclaration(n) {
282292
// resolved path will cover aliased duplicates
283293
const resolvedPath = resolver(n.source.value);
284-
const importMap = n.importKind === 'type' ? typesImported :
285-
(hasNamespace(n) ? nsImported : imported);
294+
const importMap = getImportMap(n);
286295

287296
if (importMap.has(resolvedPath)) {
288297
importMap.get(resolvedPath).push(n);
@@ -291,10 +300,11 @@ module.exports = {
291300
}
292301
},
293302

294-
'Program:exit': function () {
303+
'Program:exit'() {
295304
checkImports(imported, context);
296305
checkImports(nsImported, context);
297-
checkImports(typesImported, context);
306+
checkImports(defaultTypesImported, context);
307+
checkImports(namedTypesImported, context);
298308
},
299309
};
300310
},

‎tests/src/rules/no-duplicates.js

+64-1
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,71 @@ context('TypeScript', function() {
434434
code: "import type { x } from './foo'; import y from './foo'",
435435
...parserConfig,
436436
}),
437+
test({
438+
code: "import type x from './foo'; import type y from './bar'",
439+
...parserConfig,
440+
}),
441+
test({
442+
code: "import type {x} from './foo'; import type {y} from './bar'",
443+
...parserConfig,
444+
}),
445+
test({
446+
code: "import type x from './foo'; import type {y} from './foo'",
447+
...parserConfig,
448+
}),
449+
],
450+
invalid: [
451+
test({
452+
code: "import type x from './foo'; import type y from './foo'",
453+
...parserConfig,
454+
errors: [
455+
{
456+
line: 1,
457+
column: 20,
458+
message: "'./foo' imported multiple times.",
459+
},
460+
{
461+
line: 1,
462+
column: 48,
463+
message: "'./foo' imported multiple times.",
464+
},
465+
],
466+
}),
467+
test({
468+
code: "import type x from './foo'; import type x from './foo'",
469+
output: "import type x from './foo'; ",
470+
...parserConfig,
471+
errors: [
472+
{
473+
line: 1,
474+
column: 20,
475+
message: "'./foo' imported multiple times.",
476+
},
477+
{
478+
line: 1,
479+
column: 48,
480+
message: "'./foo' imported multiple times.",
481+
},
482+
],
483+
}),
484+
test({
485+
code: "import type {x} from './foo'; import type {y} from './foo'",
486+
...parserConfig,
487+
output: `import type {x,y} from './foo'; `,
488+
errors: [
489+
{
490+
line: 1,
491+
column: 22,
492+
message: "'./foo' imported multiple times.",
493+
},
494+
{
495+
line: 1,
496+
column: 52,
497+
message: "'./foo' imported multiple times.",
498+
},
499+
],
500+
}),
437501
],
438-
invalid: [],
439502
});
440503
});
441504
});

0 commit comments

Comments
 (0)
Please sign in to comment.