no-unsafe-negation
Disallow negating the left operand of in and instanceof
error by defaulthas suggestions
! binds tighter than in and instanceof. So !key in cache means (!key) in cache, which asks if cache has a property called "true" or "false". And !error instanceof TypeError is always false, because a boolean isn't an instance of anything.
The rule can't tell which meaning you want, so it suggests both: negate the whole expression, or put the negation in parentheses.
This rule is on by default in JavaScript files. It's off in TypeScript files, where the type checker reports the same thing.
Configure#
On by default as an error. To turn it off:
bunfig.toml
[lint.rules]
"no-unsafe-negation" = "off" # or "warn"Every option, set to its default:
bunfig.toml
[lint.rules]
"no-unsafe-negation" = ["error", {
enforceForOrderingRelations = false,
}]Examples#
example.js2 problems
if (!keyUnexpected negating the left operand of in operator. in cache) {
cache[key] = load(key);
}
if (!errorUnexpected negating the left operand of instanceof operator. instanceof TypeError) {
throw error;
}example.jsNo problems
if (!(key in cache)) {
cache[key] = load(key);
}
if (!(error instanceof TypeError)) {
throw error;
}If you do want to negate the left operand, say so with parentheses:
example.jsNo problems
const hasFlag = (!enabled) in counts;Options#
| Option | Default | What it does |
|---|---|---|
enforceForOrderingRelations | false | Also check <, >, <= and >=. |
!count < limit compares true or false with limit:
example.jswith
{ "enforceForOrderingRelations": true }1 problemif (!countUnexpected negating the left operand of < operator. < limit) {
stop();
}example.jswith
{ "enforceForOrderingRelations": true }No problemsif (!(count < limit)) {
stop();
}