no-cond-assign

Disallow assignments in the test of if, loops and ? :

warn by default

if (user.role = "admin") is usually a typo for ===. It overwrites user.role, and the branch always runs because "admin" is truthy.

The rule checks the test of if, while, do...while, for and ? :. By default, an extra pair of parentheses around the assignment marks it as intentional.

This rule is on by default.

Configure#

On by default as a warning. To turn it off:

bunfig.toml
[lint.rules]
"no-cond-assign" = "off" # or "error"

Every option, set to its default:

bunfig.toml
[lint.rules]
"no-cond-assign" = ["warn", "except-parens"] # "except-parens" or "always"

Examples#

example.js1 problem
if (user.role = "admin") {
  showSettings();
}
example.jsNo problems
if (user.role === "admin") {
  showSettings();
}

let node = list.head;
while ((node = node.next)) {
  visit(node);
}

Options#

OptionWhat it does
"except-parens" (default)Report a test that is an assignment, unless the assignment has its own parentheses.
"always"Report every assignment inside a test, with or without parentheses.

With "always", an assignment that is only part of the test is reported too:

example.jswith "always"1 problem
let match;
while ((match = pattern.exec(text)) !== null) {
  results.push(match[0]);
}

The default allows it:

example.jsNo problems
let match;
while ((match = pattern.exec(text)) !== null) {
  results.push(match[0]);
}

With the default, the test of ? : needs two pairs of parentheses. One pair is still reported:

example.js1 problem
const label = (current = next()) ? current.name : "none";
example.jsNo problems
const label = ((current = next())) ? current.name : "none";