Skip to content

Commit 1dbcd96

Browse files
committed
[Fix] no-duplicates: Ignore duplicate modules in different TypeScript module declarations
Without this the `import/no-duplicates` rule reports imports of the same module inside different module declarations in the same file. It even autofixed them, which break the code. Closes #2273
1 parent 128d505 commit 1dbcd96

File tree

3 files changed

+33
-10
lines changed

3 files changed

+33
-10
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1313

1414
### Fixed
1515
- [`default`]: `typescript-eslint-parser`: avoid a crash on exporting as namespace (thanks [@ljharb])
16+
- [`no-duplicates:`]: ignore duplicate modules in different TypeScript module declarations ([#2378], thanks [@remcohaszing])
1617

1718
### Changed
1819
- [Tests] `no-nodejs-modules`: add tests for node protocol URL ([#2367], thanks [@sosukesuzuki])

Diff for: src/rules/no-duplicates.js

+18-10
Original file line numberDiff line numberDiff line change
@@ -274,17 +274,23 @@ module.exports = {
274274
return defaultResolver(parts[1]) + '?' + parts[2];
275275
}) : defaultResolver;
276276

277-
const imported = new Map();
278-
const nsImported = new Map();
279-
const defaultTypesImported = new Map();
280-
const namedTypesImported = new Map();
277+
const moduleMaps = new Map();
281278

282279
function getImportMap(n) {
280+
if (!moduleMaps.has(n.parent)) {
281+
moduleMaps.set(n.parent, {
282+
imported: new Map(),
283+
nsImported: new Map(),
284+
defaultTypesImported: new Map(),
285+
namedTypesImported: new Map(),
286+
});
287+
}
288+
const map = moduleMaps.get(n.parent);
283289
if (n.importKind === 'type') {
284-
return n.specifiers.length > 0 && n.specifiers[0].type === 'ImportDefaultSpecifier' ? defaultTypesImported : namedTypesImported;
290+
return n.specifiers.length > 0 && n.specifiers[0].type === 'ImportDefaultSpecifier' ? map.defaultTypesImported : map.namedTypesImported;
285291
}
286292

287-
return hasNamespace(n) ? nsImported : imported;
293+
return hasNamespace(n) ? map.nsImported : map.imported;
288294
}
289295

290296
return {
@@ -301,10 +307,12 @@ module.exports = {
301307
},
302308

303309
'Program:exit': function () {
304-
checkImports(imported, context);
305-
checkImports(nsImported, context);
306-
checkImports(defaultTypesImported, context);
307-
checkImports(namedTypesImported, context);
310+
for (const map of moduleMaps.values()) {
311+
checkImports(map.imported, context);
312+
checkImports(map.nsImported, context);
313+
checkImports(map.defaultTypesImported, context);
314+
checkImports(map.namedTypesImported, context);
315+
}
308316
},
309317
};
310318
},

Diff for: tests/src/rules/no-duplicates.js

+14
Original file line numberDiff line numberDiff line change
@@ -454,6 +454,20 @@ context('TypeScript', function () {
454454
`,
455455
...parserConfig,
456456
}),
457+
test({
458+
code: `
459+
import type { Identifier } from 'module';
460+
461+
declare module 'module2' {
462+
import type { Identifier } from 'module';
463+
}
464+
465+
declare module 'module3' {
466+
import type { Identifier } from 'module';
467+
}
468+
`,
469+
...parserConfig,
470+
}),
457471
],
458472
invalid: [
459473
test({

0 commit comments

Comments
 (0)