-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[fix] export
: false positive for typescript overloads
#1412
Conversation
src/rules/export.js
Outdated
@@ -34,6 +47,7 @@ module.exports = { | |||
|
|||
create: function (context) { | |||
const namespace = new Map([[rootProgram, new Map()]]) | |||
const isTypescriptFile = /\.ts|\.tsx$/.test(context.getFilename()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this seems like something that would need to be determined based on parser settings, not hardcoded extensions - also, what about flow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Will it suffice to do something like
\/@typescript-eslint\/parser\/.test(context.parserPath)
?(context.parserPath
is like/home/some-user/some-project/node_modules/@typescript-eslint/parser/dist/parser.js
) 2. It seems that flow does not accept function overload like the case here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that would force people to install the typescript parser even if they weren’t using typescript, i think - ideally we’d find a more reliable mechanism than “its typescript” to handle this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just find out find that these function nodes without body has node type TSDeclareFunction
. Therefore I change the bail out logic to some nodes is TSDeclareFunction && every nodes is TSDeclareFunction or FunctionDeclaration
.
src/rules/export.js
Outdated
@@ -137,7 +141,7 @@ module.exports = { | |||
for (let [name, nodes] of named) { | |||
if (nodes.size <= 1) continue | |||
|
|||
if (isTypescriptFile && isTypescriptFunctionOverloads(nodes)) continue | |||
if (isTypescriptFunctionOverloads([...nodes])) continue |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the spread into an array? is nodes
not an Array, just an iterable? Set
maybe? if so I might Array.from(nodes)
to make it a little clearer. but definitely nitpicking, this is a great improvement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why not pass the Set in directly, and convert it inside the function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ready for review
src/rules/export.js
Outdated
*/ | ||
function isTypescriptFunctionOverloads(nodes) { | ||
return Array.from(nodes).some(node => node.parent.type === 'TSDeclareFunction') && | ||
Array.from(nodes).every(node => ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's definitely not do Array.from twice. maybe something like this for the body of the function?
const types = new Set(Array.from(nodes, node => node.parent.type));
if (!types.has('TSDeclareFunction') || types.size > 2) {
return false;
}
return types.size === 1 || types.has('FunctionDeclaration');
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I end up with this:
const types = new Set(Array.from(nodes, node => node.parent.type))
return types.size === 2 && types.has('TSDeclareFunction') && types.has('FunctionDeclaration')
The case when types
is the same as new Set(["TSDeclareFunction"])
is when the function lacks implementation, which is a tsc error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That isn't the same logic though - your current logic allows it to be only "TSDeclareFunction". Functions don't need an implementation in tsc if they're just defining a type overload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That case is a tsc error https://www.typescriptlang.org/play/#code/KYDwDg9gTgLgBAMwK4DsDGMCWEWIBQCUQA . And for the purpose of this rule, that case does not matter.
Fixes #1357.
Fixes false positives like this: