Skip to content

Commit

Permalink
[Fix] TypeScript: Add nested namespace handling
Browse files Browse the repository at this point in the history
  • Loading branch information
julien1619 authored and ljharb committed May 13, 2020
1 parent 8118170 commit 5cc3147
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 20 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Expand Up @@ -18,6 +18,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
- [`no-duplicates`]: Handle TS import type ([#1676], thanks [@kmui2])
- [`newline-after-import`]: recognize decorators ([#1139], thanks [@atos1990])
- [`no-unused-modules`]: Revert "[flow] `no-unused-modules`: add flow type support" ([#1770], thanks [@Hypnosphi])
- TypeScript: Add nested namespace handling ([#1763], thanks [@julien1619])

### Changed
- TypeScript config: Disable [`named`][] ([#1726], thanks [@astorije])
Expand Down Expand Up @@ -683,6 +684,7 @@ for info on changes for earlier releases.
[#1786]: https://github.com/benmosher/eslint-plugin-import/pull/1786
[#1785]: https://github.com/benmosher/eslint-plugin-import/pull/1785
[#1770]: https://github.com/benmosher/eslint-plugin-import/pull/1770
[#1763]: https://github.com/benmosher/eslint-plugin-import/pull/1763
[#1726]: https://github.com/benmosher/eslint-plugin-import/pull/1726
[#1724]: https://github.com/benmosher/eslint-plugin-import/pull/1724
[#1722]: https://github.com/benmosher/eslint-plugin-import/issues/1722
Expand Down Expand Up @@ -1167,3 +1169,4 @@ for info on changes for earlier releases.
[@Hypnosphi]: https://github.com/Hypnosphi
[@nickofthyme]: https://github.com/nickofthyme
[@manuth]: https://github.com/manuth
[@julien1619]: https://github.com/julien1619
43 changes: 24 additions & 19 deletions src/ExportMap.js
Expand Up @@ -551,26 +551,31 @@ ExportMap.parse = function (path, content, context) {
return
}
exportedDecls.forEach((decl) => {
if (decl.type === 'TSModuleDeclaration' && decl && decl.body && decl.body.body) {
decl.body.body.forEach((moduleBlockNode) => {
// Export-assignment exports all members in the namespace, explicitly exported or not.
const namespaceDecl = moduleBlockNode.type === 'ExportNamedDeclaration' ?
moduleBlockNode.declaration :
moduleBlockNode

if (namespaceDecl.type === 'VariableDeclaration') {
namespaceDecl.declarations.forEach((d) =>
recursivePatternCapture(d.id, (id) => m.namespace.set(
id.name,
captureDoc(source, docStyleParsers, decl, namespaceDecl, moduleBlockNode))
if (decl.type === 'TSModuleDeclaration') {
if (decl.body && decl.body.type === 'TSModuleDeclaration') {
m.namespace.set(decl.body.id.name, captureDoc(source, docStyleParsers, decl.body))
} else if (decl.body && decl.body.body) {
decl.body.body.forEach((moduleBlockNode) => {
// Export-assignment exports all members in the namespace,
// explicitly exported or not.
const namespaceDecl = moduleBlockNode.type === 'ExportNamedDeclaration' ?
moduleBlockNode.declaration :
moduleBlockNode

if (namespaceDecl.type === 'VariableDeclaration') {
namespaceDecl.declarations.forEach((d) =>
recursivePatternCapture(d.id, (id) => m.namespace.set(
id.name,
captureDoc(source, docStyleParsers, decl, namespaceDecl, moduleBlockNode)
))
)
)
} else {
m.namespace.set(
namespaceDecl.id.name,
captureDoc(source, docStyleParsers, moduleBlockNode))
}
})
} else {
m.namespace.set(
namespaceDecl.id.name,
captureDoc(source, docStyleParsers, moduleBlockNode))
}
})
}
} else {
// Export as default
m.namespace.set('default', captureDoc(source, docStyleParsers, decl))
Expand Down
15 changes: 15 additions & 0 deletions tests/files/typescript-declare-nested.d.ts
@@ -0,0 +1,15 @@
declare namespace foo {
interface SomeInterface {
a: string;
}
}

declare namespace foo.bar {
interface SomeOtherInterface {
b: string;
}

function MyFunction();
}

export = foo;
15 changes: 14 additions & 1 deletion tests/src/rules/namespace.js
@@ -1,4 +1,4 @@
import { test, SYNTAX_CASES } from '../utils'
import { test, SYNTAX_CASES, getTSParsers } from '../utils'
import { RuleTester } from 'eslint'

var ruleTester = new RuleTester({ env: { es6: true }})
Expand Down Expand Up @@ -120,6 +120,19 @@ const valid = [
},
}),

// Typescript
...getTSParsers().map((parser) => test({
code: `
import * as foo from "./typescript-declare-nested"
foo.bar.MyFunction()
`,
parser: parser,
settings: {
'import/parsers': { [parser]: ['.ts'] },
'import/resolver': { 'eslint-import-resolver-typescript': true },
},
})),

...SYNTAX_CASES,
]

Expand Down

0 comments on commit 5cc3147

Please sign in to comment.