Skip to content
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

Rule proposal: prefer-set-has #495

Closed
fisker opened this issue Jan 3, 2020 · 11 comments · Fixed by #604
Closed

Rule proposal: prefer-set-has #495

fisker opened this issue Jan 3, 2020 · 11 comments · Fixed by #604

Comments

@fisker
Copy link
Collaborator

fisker commented Jan 3, 2020

Enforce use Set for existence check over Array#includes.

Fail

const array = ['foo', 'bar'];

if (array.includes('foo')) {}

Pass

const set = new Set(['foo', 'bar']);

if (set.has('foo')) {}

This rule might should not fail on this

if (['foo', 'bar'].includes('foo')) {}

Maybe only check variables and check references. Also perhaps the rule name prefer-set-has ?

real world case:

const ignoredParentTypes = [
'ArrayExpression',
'IfStatement',
'MemberExpression',
'Property',
'ReturnStatement',
'VariableDeclarator'
];
const ignoredGrandparentTypes = [
'ExpressionStatement'
];

@yakov116
Copy link
Contributor

yakov116 commented Jan 3, 2020

@fisker your would need to know that the array is never used anywhere else. Maybe items are pushed on laster that will have duplicate values.

@fisker
Copy link
Collaborator Author

fisker commented Jan 3, 2020

@yakov116 Yes, need check all references only called #includes() or #indexOf(), and not exported.

@sindresorhus
Copy link
Owner

Also perhaps the rule name prefer-set-has ?

👍

Yes, need check all references only called #includes() or #indexOf(), and not exported.

I don't think it could consider indexOf as it's not just used for existence checks, and we already have a rule to enforce includes over indexOf.


I think this would be a useful rule, but I don't think it should be auto-fixable.

@sindresorhus
Copy link
Owner

Accepted

@fisker fisker changed the title Rule proposal: prefer-set Rule proposal: prefer-set-has Feb 13, 2020
@fisker
Copy link
Collaborator Author

fisker commented Mar 13, 2020

@sindresorhus Why do you think it should not auto-fixable?

I've made a prototype works fine with auto-fix.

@sindresorhus
Copy link
Owner

I guess if you can confidently check all references, it's fine.

@silverwind
Copy link
Contributor

What would be the limitations of this rule? Say a external API passes a Array. Would the rule require me to convert that to a Set first? Or does it only operate on arrays declared via literals?

@fisker
Copy link
Collaborator Author

fisker commented Mar 16, 2020

@silverwind I'm going to make it only work on ArrayExpression first, so external Array will not reported. You can help review #604

Update: I didn't exclude SpreadElement, so

Pass

import externalArray from './some-where';

const array = externalArray;
if (array.includes('foo')) {}

Fail

import externalArray from './some-where';

const array = [...externalArray]; // `array` check result can't be effected by modifying `externalArray`
if (array.includes('foo')) {}

@silverwind
Copy link
Contributor

I also wonder for cases where I have a small Array which I need to check for existance of an item but which I'd then need to pass on as Array to an external consumer. I imagine the conversation to Set and back may end up being worse performance than just calling .includes on a short array.

@fisker
Copy link
Collaborator Author

fisker commented Mar 16, 2020

You can alway use eslint-disable to disable it on small array, or we add can option to do add length check later.

@silverwind
Copy link
Contributor

silverwind commented Mar 16, 2020

Yeah of course. I generally try to avoid using eslint-disable, but this rule should still be good for manually checking a code base in a one-off fashion, but probably not something I'd generally enable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants