-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Rule proposal: no-unnecessary-coercion #8515
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
Comments
That rule exists just to do "if the A similar rule for |
I'm not sure what "issues" you're referring to. Otherwise our big argument was that it's not super common to use |
Thank you for the clarification on the Boolean rule! I do think then that something like this could cover The issue I was referring to was that for numbers, Number() has problems if it takes things like strings of spaces, so parseInt() is a better idea, and since parseInt() does not accept a string the rule is unnecessary. On the other hand for strings, String() and .toString() both work with I don't have a sense for how common it is to do casts to strings or otherwise. I feel like the rule is nice for |
Aside: this is a good example of why I'm real strict about separating "type assertion" and "cast" as terms. This issue is correct and talking about casting. But a lot of TS devs refer to type assertions as casting as well. They're not the same! (ignore me, just ranting some contextual information) |
In my head I kind of use "dynamic casting" for |
Another case occured to me that is in-line with my feelings on this, and apparently is already covered by another rule: From my perspective, checking to see if something is already guaranteed to be a string when it is cast to or asserted to be a Maybe neither here nor there, but just a thought. |
I missed somehow that no-unnecessary-type-assertion is already a rule, so this would indeed apply only to actual runtime casting. I was able to set up a development environment and started trying to make an implementation, I know there's a good chance that this will be closed without community support but I'd like the rule anyway so I'm going to give it a shot. |
I'm +1 on this. The typescript-eslint codebase itself has unnecessary
|
Closed the other one |
For the record I'm strongly in favor of reporting all unnecessary type coercions. Not just |
I implemented this, with tests, fix functions, and docs which pass yarn test, over at https://github.com/skondrashov/typescript-eslint It gives autofixable errors for: // setup
let str = "string";
const num = 1;
const bool = true;
const big = BigInt(1);
// begin invalid cases
String("hello");
"hello".toString();
"" + "hello";
"hello" + "";
String(1 + "");
(1 + "").toString();
"" + (1 + "");
1 + "" + "";
String(str);
str.toString();
"" + str;
str + "";
str += "";
Number(+"1");
+(+"1");
~~+"1";
Number(num);
+num;
~~num;
Boolean(bool);
!!bool;
BigInt(big); and allows: // setup
let str = Math.random() > 0.5 ? "string" : 1;
const num = Math.random() > 0.5 ? 1 : "1";
const bool = Math.random() > 0.5 ? true : 1;
const big = Math.random() > 0.5 ? BigInt(1) : 1;
// begin valid cases
String(str);
str.toString();
`${str}`;
"" + str;
str + "";
str += "";
new String("asdf");
Number(num);
+num;
~~num;
~1;
Boolean(bool);
!!bool;
!false;
BigInt(big); It does not do anything with "123" * 1;
"123" / 1;
"123" - 0;
"123" | 0; It also doesn't cover One thing is I don't think the word "coercion" is entirely accurate for this rule. I think "conversion" or even "type conversion idiom" might be the most precise, because I haven't opened a PR since this isn't currently accepting PRs, but I'm close to being ready to. Catches these errors within @typescript-eslint, which appear to be valid except for
|
@skondrashov Nice work btw 🙂. It's cool to see the number of spots within the typescript-eslint codebase that get fixed by your implementation (and IMO a good demo in favor of the rule). |
Noting that I think replacing explicit conversion/coercion with a |
Yeah I'm also in favor of this. Each individual case ( This might be the first time in recent memory (or ever?) an |
@skondrashov If you'd like, feel free to send a PR with your implementation 🙂 |
thanks for the warm feedback, appreciate it |
Before You File a Proposal Please Confirm You Have Done The Following...
My proposal is suitable for this project
Description
I'd like
String(something)
,something.toString()
, and perhapssomething as string
to show an error if something is astring
already, but to be allowed if it's astring | number
or even astring | number | undefined
. This is similar to the proposal at #6385 but it appears there're some issues with doing this with numbers that I don't think applies to strings.In my case, I would like to do this because I am working with a library that exports a
string | number | undefined
, but I believe their type is incorrect, and I would like to essentially be notified that I can remove my casts if the type changes and becomes astring
instead, and I believe similar use cases would not be exceeding rare, where one might be able to catch useless casts after updating one type somewhere, whether in a library or in their own type definitions. My feeling is that if this were turned on it would trigger errors in more than a couple of codebases. In reference to the similar issue for numbers, I do support the implementation of that as well for similar reasons.Fail Cases
Pass Cases
Additional Info
This is also similar to eslint's https://eslint.org/docs/latest/rules/no-extra-boolean-cast, which I'm actually not sure how they achieve without typescript, but that rule makes a lot of sense to me as well.
The text was updated successfully, but these errors were encountered: