Skip to content

Rule proposal: warn against unnecessary Number calls #6385

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

Closed
6 tasks done
kkmuffme opened this issue Jan 30, 2023 · 8 comments
Closed
6 tasks done

Rule proposal: warn against unnecessary Number calls #6385

kkmuffme opened this issue Jan 30, 2023 · 8 comments
Labels
enhancement: new plugin rule New rule request for eslint-plugin package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin wontfix This will not be worked on

Comments

@kkmuffme
Copy link

Before You File a Proposal Please Confirm You Have Done The Following...

My proposal is suitable for this project

  • My proposal specifically checks TypeScript syntax, or it proposes a check that requires type information to be accurate.
  • My proposal is not a "formatting rule"; meaning it does not just enforce how code is formatted (whitespace, brace placement, etc).
  • I believe my proposal would be useful to the broader TypeScript community (meaning it is not a niche proposal).

Description

Report unnecessary calls to Number() constructor when type is a number already

Fail Cases

https://www.typescriptlang.org/play?#code/FAYw9gdgzgLgBAMzGOBeOBtAugbmKSWOAIwEMAnNOAOQFcBbYgU3IApFkA6AGyYgHMYACzgBKPEA


const foo = [];

const bar = Number( foo.length );

Pass Cases

const replace = Number( 'me' );

Additional Info

No response

@kkmuffme kkmuffme added enhancement: new plugin rule New rule request for eslint-plugin package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin triage Waiting for team members to take a look labels Jan 30, 2023
@bradzacher
Copy link
Member

TBH in modern code one should avoid Number() because it performs a weak coercion to number. For example Number(null) === 0, Number(true) === 1, Number('Infinity') === Number.Infinity, Number(' ') === 0.

Instead using parseInt/parseFloat is much preferred because they only accept strings and don't do weird things like coercing whitespace-only strings to 0, or parsing Infinity to the global Infinity value - they are all around much stricter.
They also strictly typed to only accept strings - meaning TS will error if you attempt to do something like parseInt(0).

I'm not 100% sold on this being something that's of great value given the above and given that step 1 of the number coercion algorithm is "if number return" - so it will be super low cost to have useless Number()'s in the codebase.

Would love to hear more feedback from others (cc @JoshuaKGoldberg).

@bradzacher bradzacher added the evaluating community engagement we're looking for community engagement on this issue to show that this problem is widely important label Jan 30, 2023
@kkmuffme
Copy link
Author

This perhaps not only applies to Number() but also report unnecessary parseInt/parseFloat?

@bradzacher
Copy link
Member

@kkmuffme you can't really have an unnecessary parseInt/parseFloat because they are typed to only accept string.
So the only way it could be unnecessary is if you pass a string literal or regex literal typed value that clearly would make the function return NaN.

@bradzacher bradzacher changed the title Rule proposal: <a short description of my proposal> Rule proposal: warn against unnecessary Number calls Jan 30, 2023
@JoshuaKGoldberg
Copy link
Member

Maybe a general-purpose rule for unnecessary Boolean(...), Number(...), String(...), and similar? I'm mildly in favor for this, but not very passionate about it. 😄

@Josh-Cena
Copy link
Member

On MDN, I'm always slightly in favor of Number(). parseInt() does not allow 0x/0b/0o prefixes, and its behavior of automatically ignoring invalid suffixes may not be desirable. If JavaScript is going to implicitly coerce your string to a number, it uses the same algorithm as Number() anyway, so I think the consistency of using the same coercion algorithm is more desirable than debating whether Number("") should be NaN or 0. (BigInt("") also returns 0n—that's another argument for consistency.)

@kkmuffme
Copy link
Author

kkmuffme commented Feb 1, 2023

@JoshuaKGoldberg yes exactly, that's what I had in mind originally too.

@Josh-Cena agree with that

@bradzacher
Copy link
Member

parseInt() does not allow 0x/0b/0o prefixes

How often do you need to parse input that's possibly in any of the valid, fully-qualified bases?!?
Like - I get that it might be nice - but I don't know of a case where you would actually want that behaviour aside from some super niche dev tools.

Personally I can count the number of times I've written something other than parseInt(str) / parseInt(str, 10) on one hand.

@bradzacher
Copy link
Member

It's been a month and this issue has garnered no additional reactions or comments from the community. As such I'm going to close and reject this from the plugin, as it does not appear to represent a problem the wider community is interested in.

@bradzacher bradzacher closed this as not planned Won't fix, can't repro, duplicate, stale Mar 6, 2023
@bradzacher bradzacher added wontfix This will not be worked on and removed triage Waiting for team members to take a look evaluating community engagement we're looking for community engagement on this issue to show that this problem is widely important labels Mar 6, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement: new plugin rule New rule request for eslint-plugin package: eslint-plugin Issues related to @typescript-eslint/eslint-plugin wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

4 participants