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 String#includes over String#indexOf #4209

Closed
sindresorhus opened this issue Oct 20, 2015 · 19 comments
Closed

Rule proposal: Prefer String#includes over String#indexOf #4209

sindresorhus opened this issue Oct 20, 2015 · 19 comments
Labels
archived due to age This issue has been archived; please open a new issue for any further discussion enhancement This change enhances an existing feature of ESLint evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion help wanted The team would welcome a contribution from the community for this issue rule Relates to ESLint's core rules

Comments

@sindresorhus
Copy link
Contributor

With ES2015, it's more succinct to use 'foobar'.includes('foo') instead of 'foobar'.indexOf('foo') !== -1 or 'foobar'.indexOf('foo') >= 0 for checking whether a string contains a substring. I would like a rule that enforces this in those two scenarios and the negative cases of that: 'foobar'.indexOf('foo') === -1 and 'foobar'.indexOf('foo') < 0.

Suggested rule name: prefer-string-includes

I think this would be a good rule as .includes makes the code intent clearer.

There's already other rules that enforces new ES2015 features, so it seems natural to have a rule for this too.

@eslintbot
Copy link

Thanks for the issue! If you're reporting a bug, please be sure to include:

  1. The version of ESLint you are using (run eslint -v)
  2. What you did (the source code and ESLint configuration)
  3. The actual ESLint output complete with numbers
  4. What you expected to happen instead

Requesting a new rule? Please see Proposing a New Rule for instructions.

@eslintbot eslintbot added the triage An ESLint team member will look at this issue soon label Oct 20, 2015
@alberto alberto added enhancement This change enhances an existing feature of ESLint rule Relates to ESLint's core rules evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion and removed triage An ESLint team member will look at this issue soon labels Oct 20, 2015
@nzakas nzakas added the help wanted The team would welcome a contribution from the community for this issue label Oct 20, 2015
@nzakas
Copy link
Member

nzakas commented Oct 20, 2015

Seems reasonable. Do you want to submit a PR?

@nzakas nzakas added accepted There is consensus among the team that this change meets the criteria for inclusion evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion and removed evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion accepted There is consensus among the team that this change meets the criteria for inclusion labels Oct 20, 2015
@nzakas
Copy link
Member

nzakas commented Oct 21, 2015

Looking at this again, it looks like this would only be possible with string literals since we have no way of knowing if a variable contains a string or not. Given that, I think I was too hasty in marking this accepted, as I don't think there's a good way to do this nor do I think a rule that applies only to string literals is all that useful (since if you have a string literal, you can see if a substring is included).

When includes is added for arrays, we can probably look at a more general rule that always suggests it regardless of type. It seems we are just too early for that.

@sindresorhus
Copy link
Contributor Author

I guess this is yet another case where some kind of type inference would be useful.

@nzakas
Copy link
Member

nzakas commented Oct 21, 2015

Yup. Or alternately, if every type that has indexOf also has includes, then the type doesn't matter. Sadly since Array.prototype.includes didn't make it into ES6, we are left with weirdness.

@sindresorhus
Copy link
Contributor Author

TypedArray also has includes btw (ES2016). Even though Array#includes is ES2016, it's already in Chrome 47, Firefox 43, Safari 9.

@xjamundx
Copy link
Contributor

We have a stupidly simple version of this that we use at PayPal:

module.exports = function(context) {
     return {
        'MemberExpression': function(node) {
            if (node.property.name === 'indexOf') {
                context.report(node, 'Expected .includes() instead of .indexOf().');
            }
        }
    };
};

@nzakas
Copy link
Member

nzakas commented Nov 13, 2015

Yeah, it's not hard to make, it's just inaccurate, which is why we can't have it as part of core right now.

@platinumazure
Copy link
Member

@nzakas Noticing this issue is open and has "help wanted" label, but not "accepted" (and comments seem to indicate this won't be accepted). Should the issue be closed and/or should the "help wanted" label be removed?

@nzakas
Copy link
Member

nzakas commented Dec 1, 2015

Hmm, good point. Should be closed, thanks.

@sindresorhus
Copy link
Contributor Author

@nzakas I noticed you added the array-callback-return rule, which says:

This rule checks callback functions of methods with the given names, even if the object which has the method is not an array.

That was pretty much the main argument against this rule, so would you be willing to reconsider this?

@nzakas
Copy link
Member

nzakas commented May 2, 2016

Not quite the same, but since it looks like includes is making its way into browsers for arrays, it's probably less of an issue now.

Even so, I'm not sure this is important enough to be a core rule. I'll reopen to see if anyone feels differently.

@nzakas nzakas reopened this May 2, 2016
@nzakas
Copy link
Member

nzakas commented Aug 3, 2016

Okay, it's been another three months without movement, so closing.

@nzakas nzakas closed this as completed Aug 3, 2016
@rodrigok
Copy link

@alxndr are you planing to submit a PR?

@alxndr
Copy link

alxndr commented Mar 28, 2017

I wasn't, but I can make one if there's still interest.

@ilyavolodin
Copy link
Member

This can now be implemented as an option for no-restricted-syntax rule:

"no-restricted-syntax": ["error", "BinaryExpression > CallExpression > MemberExpression > Identifier[name = 'indexOf']"]

So I don't think this should be added to the core.

@vitorbal
Copy link
Member

Agreed with @ilyavolodin, especially since very soon you will also be able to provide custom messages for no-restricted-syntax: #8298

@mnoorenberghe
Copy link

This can now be implemented as an option for no-restricted-syntax rule:

"no-restricted-syntax": ["error", "BinaryExpression > CallExpression > MemberExpression > Identifier[name = 'indexOf']"]

That doesn't address the original comment of only being an error when comparing with -1 and 0 since indexOf is the correct tool otherwise. Does "no-restricted-syntax" handle that?

@rodrigok
Copy link

I don't think no-restricted-syntax as a good option for that, or we should use it for all rules 😄
It can be a work around, but will not be easy to configure for important things like replace indexOf by the new method includes

@eslint-deprecated eslint-deprecated bot locked and limited conversation to collaborators Feb 7, 2018
@eslint-deprecated eslint-deprecated bot added the archived due to age This issue has been archived; please open a new issue for any further discussion label Feb 7, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
archived due to age This issue has been archived; please open a new issue for any further discussion enhancement This change enhances an existing feature of ESLint evaluating The team will evaluate this issue to decide whether it meets the criteria for inclusion help wanted The team would welcome a contribution from the community for this issue rule Relates to ESLint's core rules
Projects
None yet
Development

No branches or pull requests