sindresorhus / eslint-plugin-unicorn

More than 100 powerful ESLint rules

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Rule proposal: no-confusing-conditions

mmkal opened this issue · comments

Description

It's hard to look at conditions with mixed && and || operators and intuitively remember 3,712 words on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_precedence. There should be a rule that forces you to use parentheses for clarity and readability, even when to the JS engine, it's unambiguous.

Fail

a && b || c;
a || b * c;
a && b < c;
a ?? b || c;

Pass

Explicit parens (not auto-fixable) are ok:

a && (b || c);
a || (b * c);
a && (b < c);
a ?? (b || c);

The rule shouldn't have an opinion on where parens are ok

(a && b) || c;
(a || b) * c;
(a && b) < c;
(a ?? b) || c;

Chained operators should be ok:

a && b && c
a || b || c
a ?? b ?? c

Familiar maths expressions taught to schoolchildren (BODMAS/PEMDAS) shouldn't be punished:

a ** b + c
a - b / c
a * b ** c

Additional Info

It should probably be implemented in a way such that all expressions with more than one operator are flagged, unless they are known to be OK, so that any missed cases are assumed to be needing-parentheses.

Rough allowlist implementation off the top of my head:

const mathsOperators = new Set(['+', '-', '*', '/', '**'])
const isok =
  operators.length <= 1
  || operators.every(op === operators[0])
  || operators.every(op => mathsOperators.has(op))

But implementing and testing would probably reveal more cases where it's not ambiguous, and not worth the extra verbosity.


Having written all that, I did find https://eslint.style/rules/js/no-mixed-operators - I'm not sure what the policy is on rules that exist elsewhere, there's other overlap between eslint-plugin-unicorn and @stylistic/eslint-plugin-js so maybe worth adding here too? I didn't actually know @stylistic/eslint-plugin-js existed, so not sure what the policy is.

I'm not sure what the policy is on rules that exist elsewhere, there's other overlap between eslint-plugin-unicorn and @stylistic/eslint-plugin-js so maybe worth adding here too? I didn't actually know @stylistic/eslint-plugin-js existed, so not sure what the policy is.

If we could make a rule better, it may make sense sometimes, but in this case, you should just use no-mixed-operators.