Skip to content

Commit

Permalink
[fix] no-duplicates: correctly handle case of mixed default/named t…
Browse files Browse the repository at this point in the history
…ype imports

Co-authored-by: Nathan Walters <nwalters@nerdwallet.com>
Co-authored-by: Gord Pearson <gord.pearson@shopify.com>
  • Loading branch information
2 people authored and ljharb committed Aug 17, 2021
1 parent 3977c42 commit 712ee49
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 8 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
### Fixed
- `ExportMap`: Add default export when esModuleInterop is true and anything is exported ([#2184], thanks [@Maxim-Mazurok])
- [`named`], [`namespace`]: properly set reexports on `export * as … from` ([#1998], [#2161], thanks [@ljharb])
- [`no-duplicates`]: correctly handle case of mixed default/named type imports ([#2149], thanks [@GoodForOneFare], [@nwalters512])

### Changed
- [Docs] `max-dependencies`: 📖 Document `ignoreTypeImports` option ([#2196], thanks [@himynameisdave])
Expand Down Expand Up @@ -897,6 +898,7 @@ for info on changes for earlier releases.
[#2160]: https://github.com/import-js/eslint-plugin-import/pull/2160
[#2158]: https://github.com/import-js/eslint-plugin-import/pull/2158
[#2156]: https://github.com/import-js/eslint-plugin-import/pull/2156
[#2149]: https://github.com/benmosher/eslint-plugin-import/pull/2149
[#2146]: https://github.com/import-js/eslint-plugin-import/pull/2146
[#2140]: https://github.com/import-js/eslint-plugin-import/pull/2140
[#2138]: https://github.com/import-js/eslint-plugin-import/pull/2138
Expand Down Expand Up @@ -1404,6 +1406,7 @@ for info on changes for earlier releases.
[@gavriguy]: https://github.com/gavriguy
[@giodamelio]: https://github.com/giodamelio
[@golopot]: https://github.com/golopot
[@GoodForOneFare]: https://github.com/GoodForOneFare
[@graingert]: https://github.com/graingert
[@grit96]: https://github.com/grit96
[@guillaumewuip]: https://github.com/guillaumewuip
Expand Down Expand Up @@ -1471,6 +1474,7 @@ for info on changes for earlier releases.
[@nicolashenry]: https://github.com/nicolashenry
[@noelebrun]: https://github.com/noelebrun
[@ntdb]: https://github.com/ntdb
[@nwalters512]: https://github.com/nwalters512
[@panrafal]: https://github.com/panrafal
[@paztis]: https://github.com/paztis
[@pcorpet]: https://github.com/pcorpet
Expand Down Expand Up @@ -1533,4 +1537,4 @@ for info on changes for earlier releases.
[@wtgtybhertgeghgtwtg]: https://github.com/wtgtybhertgeghgtwtg
[@xpl]: https://github.com/xpl
[@yordis]: https://github.com/yordis
[@zloirock]: https://github.com/zloirock
[@zloirock]: https://github.com/zloirock
22 changes: 16 additions & 6 deletions src/rules/no-duplicates.js
Expand Up @@ -276,13 +276,22 @@ module.exports = {

const imported = new Map();
const nsImported = new Map();
const typesImported = new Map();
const defaultTypesImported = new Map();
const namedTypesImported = new Map();

function getImportMap(n) {
if (n.importKind === 'type') {
return n.specifiers[0].type === 'ImportDefaultSpecifier' ? defaultTypesImported : namedTypesImported;
}

return hasNamespace(n) ? nsImported : imported;
}

return {
'ImportDeclaration': function (n) {
ImportDeclaration(n) {
// resolved path will cover aliased duplicates
const resolvedPath = resolver(n.source.value);
const importMap = n.importKind === 'type' ? typesImported :
(hasNamespace(n) ? nsImported : imported);
const importMap = getImportMap(n);

if (importMap.has(resolvedPath)) {
importMap.get(resolvedPath).push(n);
Expand All @@ -291,10 +300,11 @@ module.exports = {
}
},

'Program:exit': function () {
'Program:exit'() {
checkImports(imported, context);
checkImports(nsImported, context);
checkImports(typesImported, context);
checkImports(defaultTypesImported, context);
checkImports(namedTypesImported, context);
},
};
},
Expand Down
65 changes: 64 additions & 1 deletion tests/src/rules/no-duplicates.js
Expand Up @@ -434,8 +434,71 @@ context('TypeScript', function() {
code: "import type { x } from './foo'; import y from './foo'",
...parserConfig,
}),
test({
code: "import type x from './foo'; import type y from './bar'",
...parserConfig,
}),
test({
code: "import type {x} from './foo'; import type {y} from './bar'",
...parserConfig,
}),
test({
code: "import type x from './foo'; import type {y} from './foo'",
...parserConfig,
}),
],
invalid: [
test({
code: "import type x from './foo'; import type y from './foo'",
...parserConfig,
errors: [
{
line: 1,
column: 20,
message: "'./foo' imported multiple times.",
},
{
line: 1,
column: 48,
message: "'./foo' imported multiple times.",
},
],
}),
test({
code: "import type x from './foo'; import type x from './foo'",
output: "import type x from './foo'; ",
...parserConfig,
errors: [
{
line: 1,
column: 20,
message: "'./foo' imported multiple times.",
},
{
line: 1,
column: 48,
message: "'./foo' imported multiple times.",
},
],
}),
test({
code: "import type {x} from './foo'; import type {y} from './foo'",
...parserConfig,
output: `import type {x,y} from './foo'; `,
errors: [
{
line: 1,
column: 22,
message: "'./foo' imported multiple times.",
},
{
line: 1,
column: 52,
message: "'./foo' imported multiple times.",
},
],
}),
],
invalid: [],
});
});
});

0 comments on commit 712ee49

Please sign in to comment.