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: no-implicit-conversion #2448

Open
axetroy opened this issue Sep 10, 2024 · 3 comments
Open

Rule proposal: no-implicit-conversion #2448

axetroy opened this issue Sep 10, 2024 · 3 comments

Comments

@axetroy
Copy link
Contributor

axetroy commented Sep 10, 2024

Description

When using the +/- operator with strings and numbers.

There are many traps here, and things can go wrong.

e.g.

let result = '5' + 3;
console.log(result); // '53' - String concatenation

let result = '5' - 3;
console.log(result); // 2 - The string is converted to a number

result = 3 + '5';
console.log(result); // '35' - Still string concatenation

let result = '10' - 3;
console.log(result); // 7 - The string '10' is converted to the number 10

result = '5' - '2';
console.log(result); // 3 - Both strings are converted to numbers and then subtracted

I know, no one would write code like this in the real world

But there will be the following situation

function foo() {
  // ...other logic
  return "5"
}

// ... other logic

const bar = foo() + 5 // ❌

We should check that left and right expression are of the same type to avoid implicit conversion.

It is feasible when we can infer its type, skip check when found any/unknown/never.

There is no possibility of false positives

Fail

Plus operator:

const foo = "5" // numberic

// ... other logic

const bar = foo + 5 // ❌
function foo() {
  return "5"
}

// ... other logic

const bar = foo() + 5 // ❌

Minus operator:

const foo = "10"

// ...other logic

const bar = foo - 5 // ❌

Type Annotation:

let foo: string

// ...other logic

const bar = foo - 5 // ❌
let foo = (): string => {}

// ...other logic

const bar = foo() - 5 // ❌
function foo (bar: string) {
  bar - 5 // ❌
}

Pass

const foo = "5"

// ... other logic

const bar = Number(foo) + 5 // ✅
function foo() {
  return "5"
}

// ... other logic

const bar = Number(foo()) + 5 // ✅

Minus operator:

const foo = "10"

// ...other logic

const bar = Number(foo) - 5 // ✅

Proposed rule name

no-implicit-conversion

Additional Info

No response

@fisker
Copy link
Collaborator

fisker commented Sep 10, 2024

This is hard to detect, but

1e13 - new Date(); // -> number

1e13 + new Date(); // -> string

@fregante
Copy link
Collaborator

fregante commented Sep 10, 2024

If the code is in TS this is redundant, so the “type annotation” examples shouldn’t be considered.

For the rest, this would only work in the limited cases where the value (and therefore its type) is defined locally. It kinda makes sense as a rule but also people who care about this just use TypeScript. By this I mean that outside TS people generally take advantage of JS’ dynamicity and don’t like the verbosity of Number(str) - 1.

The only scenario where this would actually be beneficial (i.e. prevent bugs) is on str + number, but it feels like this rarely happens when str is declared locally.

Just my 2c, this rule wouldn’t affect me as I use TS almost exclusively.

@zanminkian
Copy link
Contributor

TypeScript can detect this. If user use JavaScript, they need to tolerate the type-safe problems about JavaScript. IMO, ESLint should not repeat the functions belonging to TS.

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

No branches or pull requests

4 participants