From 5cc31478a12c138b382e8efa97275db945b80562 Mon Sep 17 00:00:00 2001 From: Julien Blatecky Date: Wed, 13 May 2020 16:59:09 +0200 Subject: [PATCH] [Fix] TypeScript: Add nested namespace handling --- CHANGELOG.md | 3 ++ src/ExportMap.js | 43 ++++++++++++---------- tests/files/typescript-declare-nested.d.ts | 15 ++++++++ tests/src/rules/namespace.js | 15 +++++++- 4 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 tests/files/typescript-declare-nested.d.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index baae8d2e2..b9cfe0d71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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]) @@ -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 @@ -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 diff --git a/src/ExportMap.js b/src/ExportMap.js index 5a36b220b..b53d252a3 100644 --- a/src/ExportMap.js +++ b/src/ExportMap.js @@ -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)) diff --git a/tests/files/typescript-declare-nested.d.ts b/tests/files/typescript-declare-nested.d.ts new file mode 100644 index 000000000..dc6b0049a --- /dev/null +++ b/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; diff --git a/tests/src/rules/namespace.js b/tests/src/rules/namespace.js index cfc6305d5..cac18c62a 100644 --- a/tests/src/rules/namespace.js +++ b/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 }}) @@ -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, ]