From 04e114b686bd5acab887ebacaa3b178ea264c96a Mon Sep 17 00:00:00 2001 From: Jordan Harband Date: Sat, 27 Aug 2022 22:23:53 -0700 Subject: [PATCH] [Fix] `export`: do not error on TS export overloads Fixes #1590 --- CHANGELOG.md | 2 ++ src/rules/export.js | 32 ++++++++++++++++++++++++++------ tests/src/rules/export.js | 11 +++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1bbceb50..dfa64512c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange - [`order`]: leave more space in rankings for consecutive path groups ([#2506], thanks [@Pearce-Ropion]) - [`no-cycle`]: add ExportNamedDeclaration statements to dependencies ([#2511], thanks [@BenoitZugmeyer]) - [`dynamic-import-chunkname`]: prevent false report on a valid webpack magic comment ([#2330], thanks [@mhmadhamster]) +- [`export`]: do not error on TS export overloads ([#1590], thanks [@ljharb]) ### Changed - [Tests] [`named`]: Run all TypeScript test ([#2427], thanks [@ProdigySim]) @@ -1341,6 +1342,7 @@ for info on changes for earlier releases. [#1631]: https://github.com/import-js/eslint-plugin-import/issues/1631 [#1616]: https://github.com/import-js/eslint-plugin-import/issues/1616 [#1613]: https://github.com/import-js/eslint-plugin-import/issues/1613 +[#1590]: https://github.com/import-js/eslint-plugin-import/issues/1590 [#1589]: https://github.com/import-js/eslint-plugin-import/issues/1589 [#1565]: https://github.com/import-js/eslint-plugin-import/issues/1565 [#1366]: https://github.com/import-js/eslint-plugin-import/issues/1366 diff --git a/src/rules/export.js b/src/rules/export.js index 4cae10740..5d430360a 100644 --- a/src/rules/export.js +++ b/src/rules/export.js @@ -1,6 +1,7 @@ import ExportMap, { recursivePatternCapture } from '../ExportMap'; import docsUrl from '../docsUrl'; import includes from 'array-includes'; +import flatMap from 'array.prototype.flatmap'; /* Notes on TypeScript namespaces aka TSModuleDeclaration: @@ -35,12 +36,31 @@ const tsTypePrefix = 'type:'; * @returns {boolean} */ function isTypescriptFunctionOverloads(nodes) { - const types = new Set(Array.from(nodes, node => node.parent.type)); - return types.has('TSDeclareFunction') - && ( - types.size === 1 - || (types.size === 2 && types.has('FunctionDeclaration')) - ); + const nodesArr = Array.from(nodes); + const types = new Set(nodesArr.map(node => node.parent.type)); + + const idents = flatMap(nodesArr, (node) => ( + node.declaration && ( + node.declaration.type === 'TSDeclareFunction' // eslint 6+ + || node.declaration.type === 'TSEmptyBodyFunctionDeclaration' // eslint 4-5 + ) + ? node.declaration.id.name + : [] + )); + if (new Set(idents).size !== idents.length) { + return true; + } + + if (!types.has('TSDeclareFunction')) { + return false; + } + if (types.size === 1) { + return true; + } + if (types.size === 2 && types.has('FunctionDeclaration')) { + return true; + } + return false; } /** diff --git a/tests/src/rules/export.js b/tests/src/rules/export.js index 5996e9fa3..95093bf4a 100644 --- a/tests/src/rules/export.js +++ b/tests/src/rules/export.js @@ -45,6 +45,17 @@ ruleTester.run('export', rule, { ecmaVersion: 2020, }, })) || [], + + getTSParsers().map((parser) => ({ + code: ` + export default function foo(param: string): boolean; + export default function foo(param: string, param1: number): boolean; + export default function foo(param: string, param1?: number): boolean { + return param && param1; + } + `, + parser, + })), ), invalid: [].concat(