Skip to content

Commit e9518c4

Browse files
magarcialjharb
authored andcommitted
[Fix] export: false positive for typescript namespace merging
Fixes #1964.
1 parent fc98de2 commit e9518c4

File tree

3 files changed

+49
-2
lines changed

3 files changed

+49
-2
lines changed

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1010
- [`no-named-default`, `no-default-export`, `prefer-default-export`, `no-named-export`, `export`, `named`, `namespace`, `no-unused-modules`]: support arbitrary module namespace names ([#2358], thanks [@sosukesuzuki])
1111
- [`no-dynamic-require`]: support dynamic import with espree ([#2371], thanks [@sosukesuzuki])
1212

13+
### Fixed
14+
- [`export`]/TypeScript: false positive for typescript namespace merging ([#2375], thanks [@magarcia])
15+
1316
### Changed
1417
- [Tests] `no-nodejs-modules`: add tests for node protocol URL ([#2367], thanks [@sosukesuzuki])
1518
- [Tests] `default`, `no-anonymous-default-export`, `no-mutable-exports`, `no-named-as-default-member`, `no-named-as-default`: add tests for arbitrary module namespace names ([#2358], thanks [@sosukesuzuki])
@@ -964,6 +967,7 @@ for info on changes for earlier releases.
964967

965968
[`memo-parser`]: ./memo-parser/README.md
966969

970+
[#2375]: https://github.com/import-js/eslint-plugin-import/pull/2375
967971
[#2371]: https://github.com/import-js/eslint-plugin-import/pull/2371
968972
[#2367]: https://github.com/import-js/eslint-plugin-import/pull/2367
969973
[#2332]: https://github.com/import-js/eslint-plugin-import/pull/2332
@@ -1571,6 +1575,7 @@ for info on changes for earlier releases.
15711575
[@ludofischer]: https://github.com/ludofischer
15721576
[@lukeapage]: https://github.com/lukeapage
15731577
[@lydell]: https://github.com/lydell
1578+
[@magarcia]: https://github.com/magarcia
15741579
[@Mairu]: https://github.com/Mairu
15751580
[@malykhinvi]: https://github.com/malykhinvi
15761581
[@manovotny]: https://github.com/manovotny
@@ -1661,4 +1666,4 @@ for info on changes for earlier releases.
16611666
[@wtgtybhertgeghgtwtg]: https://github.com/wtgtybhertgeghgtwtg
16621667
[@xpl]: https://github.com/xpl
16631668
[@yordis]: https://github.com/yordis
1664-
[@zloirock]: https://github.com/zloirock
1669+
[@zloirock]: https://github.com/zloirock

src/rules/export.js

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,27 @@ function isTypescriptFunctionOverloads(nodes) {
4545
);
4646
}
4747

48+
/**
49+
* Detect merging Namespaces with Classes, Functions, or Enums like:
50+
* ```ts
51+
* export class Foo { }
52+
* export namespace Foo { }
53+
* ```
54+
* @param {Set<Object>} nodes
55+
* @returns {boolean}
56+
*/
57+
function isTypescriptNamespaceMerging(nodes) {
58+
const types = new Set(Array.from(nodes, (node) => node.parent.type));
59+
return (
60+
types.has('TSModuleDeclaration') &&
61+
(types.size === 1 ||
62+
(types.size === 2 && (
63+
types.has('ClassDeclaration') || types.has('FunctionDeclaration') || types.has('TSEnumDeclaration')
64+
))
65+
)
66+
);
67+
}
68+
4869
module.exports = {
4970
meta: {
5071
type: 'problem',
@@ -156,7 +177,7 @@ module.exports = {
156177
for (const [name, nodes] of named) {
157178
if (nodes.size <= 1) continue;
158179

159-
if (isTypescriptFunctionOverloads(nodes)) continue;
180+
if (isTypescriptFunctionOverloads(nodes) || isTypescriptNamespaceMerging(nodes)) continue;
160181

161182
for (const node of nodes) {
162183
if (name === 'default') {

tests/src/rules/export.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,27 @@ context('TypeScript', function () {
219219
}
220220
`,
221221
}, parserConfig)),
222+
test(Object.assign({
223+
code: `
224+
export class Foo { }
225+
export namespace Foo { }
226+
export namespace Foo {
227+
export class Bar {}
228+
}
229+
`,
230+
}, parserConfig)),
231+
test(Object.assign({
232+
code: `
233+
export function Foo() { }
234+
export namespace Foo { }
235+
`,
236+
}, parserConfig)),
237+
test(Object.assign({
238+
code: `
239+
export enum Foo { }
240+
export namespace Foo { }
241+
`,
242+
}, parserConfig)),
222243
test(Object.assign({
223244
code: 'export * from "./file1.ts"',
224245
filename: testFilePath('typescript-d-ts/file-2.ts'),

0 commit comments

Comments
 (0)