How to Fix ESLint Error: Unnecessary Use of Boolean Literals in JavaScript Conditional Expressions When Checking Array Values
If you’ve ever run ESLint on your JavaScript project and encountered an error like “Unnecessary use of boolean literal in conditional expression”, you’re not alone. This common issue arises when developers explicitly compare boolean literals (true or false) with array method results that already return booleans (e.g., Array.prototype.includes(), Array.prototype.some()). While the code may work, these redundant checks make your code bloated and harder to read.
In this guide, we’ll break down why this error occurs, how to identify problematic patterns when checking array values, and step-by-step solutions to refactor your code for clarity and conciseness. By the end, you’ll understand how to leverage JavaScript’s built-in array methods effectively and write cleaner, more maintainable conditionals.
Table of Contents#
- Understanding the ESLint Error
- Common Scenarios with Array Checks
- How ESLint Detects This Issue
- Step-by-Step Fixes for Common Cases
- Advanced Refactoring Scenarios
- Best Practices to Avoid the Error
- Conclusion
- References
Understanding the ESLint Error#
What Triggers the Error?#
The ESLint error “Unnecessary use of boolean literal in conditional expression” is thrown by the no-unnecessary-boolean-literal-compare rule. This rule flags code where a boolean literal (true/false) is compared with an expression that already returns a boolean value.
For example:
// ❌ Unnecessary boolean literal comparison
if (myArray.includes("value") === true) { ... } Here, myArray.includes("value") already returns a boolean (true or false). Comparing it to true is redundant—like saying, “Is it true that it’s true?”
Why This Matters#
Redundant boolean checks:
- Make code harder to read (extra cognitive load for developers).
- Increase the risk of typos (e.g., accidentally writing
= trueinstead of=== true). - Clutter your codebase with unnecessary syntax.
Common Scenarios with Array Checks#
Array methods like includes(), some(), and every() return boolean values, making them prime candidates for this error. Let’s explore the most frequent problematic patterns.
Scenario 1: Comparing includes() with true/false#
Array.prototype.includes() checks if an array contains a value and returns true or false.
❌ Problematic Code:
const fruits = ["apple", "banana", "cherry"];
// Unnecessary comparison with `true`
if (fruits.includes("banana") === true) {
console.log("Banana is present!");
}
// Unnecessary comparison with `false`
if (fruits.includes("grape") === false) {
console.log("Grape is missing!");
} Scenario 2: Comparing some()/every() with true/false#
Array.prototype.some() returns true if at least one element passes a test; every() returns true if all elements pass. Both return booleans.
❌ Problematic Code:
const numbers = [1, 2, 3, 4, 5];
// `some()` checks for even numbers
if (numbers.some(num => num % 2 === 0) === true) {
console.log("There's an even number!");
}
// `every()` checks if all are positive
if (numbers.every(num => num > 0) === false) {
console.log("Not all numbers are positive!");
} Scenario 3: Overcomplicating indexOf() Checks#
Array.prototype.indexOf() returns the index of a value (or -1 if not found). While it doesn’t return a boolean, developers often compare its result to -1 and then add redundant boolean checks.
❌ Problematic Code:
const colors = ["red", "green", "blue"];
// Unnecessary `=== true` after checking index
if (colors.indexOf("green") !== -1 === true) {
console.log("Green is in the array!");
} How ESLint Detects This Issue#
ESLint’s no-unnecessary-boolean-literal-compare rule analyzes conditional expressions (e.g., if, while, ternary operators) to find:
- Comparisons like
expr === trueorexpr === false, whereexpralready returns a boolean. - Redundant checks in ternary operators:
expr === true ? a : b.
By default, this rule is enabled in most ESLint configurations (e.g., eslint:recommended), so you’ll see the error as soon as you run ESLint on your code.
Step-by-Step Fixes for Common Cases#
The solution is simple: remove the redundant boolean literal comparison and leverage the boolean return value directly.
Fix for Scenario 1: Simplify includes() Checks#
Since includes() returns a boolean, use it directly in the conditional.
✅ Fixed Code:
const fruits = ["apple", "banana", "cherry"];
// Directly use the boolean result
if (fruits.includes("banana")) {
console.log("Banana is present!");
}
// Use `!` to invert the boolean for "false" checks
if (!fruits.includes("grape")) {
console.log("Grape is missing!");
} Fix for Scenario 2: Simplify some()/every() Checks#
Similarly, some() and every() return booleans—no need for extra comparisons.
✅ Fixed Code:
const numbers = [1, 2, 3, 4, 5];
// Use `some()` directly
if (numbers.some(num => num % 2 === 0)) {
console.log("There's an even number!");
}
// Use `!` to invert `every()` for "false" checks
if (!numbers.every(num => num > 0)) {
console.log("Not all numbers are positive!");
} Fix for Scenario 3: Clean Up indexOf() Checks#
indexOf() returns a number, so we first check !== -1 to get a boolean, but avoid adding === true.
✅ Fixed Code:
const colors = ["red", "green", "blue"];
// Remove the redundant `=== true`
if (colors.indexOf("green") !== -1) {
console.log("Green is in the array!");
} Advanced Refactoring Scenarios#
Let’s tackle more complex cases, such as nested conditionals or combined checks.
Case 1: Nested Conditionals with Redundant Checks#
❌ Problematic Code:
const users = [
{ id: 1, name: "Alice", isAdmin: true },
{ id: 2, name: "Bob", isAdmin: false }
];
// Nested redundant checks
if (users.some(user => user.isAdmin) === true) {
if (users.every(user => user.id > 0) === true) {
console.log("All users have valid IDs and there's an admin!");
}
} ✅ Fixed Code:
// Simplify nested conditionals by removing redundant checks
if (users.some(user => user.isAdmin) && users.every(user => user.id > 0)) {
console.log("All users have valid IDs and there's an admin!");
} Case 2: Ternary Operators with Redundant Booleans#
❌ Problematic Code:
const hasPermission = roles.includes("editor") === true ? "Yes" : "No"; ✅ Fixed Code:
const hasPermission = roles.includes("editor") ? "Yes" : "No"; Case 3: Combining Multiple Redundant Checks#
❌ Problematic Code:
const items = [10, 20, 30];
if (items.includes(10) === true && items.includes(40) === false) {
console.log("10 is present, 40 is missing!");
} ✅ Fixed Code:
if (items.includes(10) && !items.includes(40)) {
console.log("10 is present, 40 is missing!");
} Best Practices to Avoid the Error#
-
Know Your Array Method Returns
includes(),some(),every()→ returnboolean.indexOf(),findIndex()→ returnnumber(use!== -1for presence checks).find()→ returns the element orundefined(use truthiness:if (findResult)).
-
Leverage
!for “False” Checks
Instead ofexpr === false, use!expr(e.g.,!arr.includes(x)instead ofarr.includes(x) === false). -
Configure ESLint Early
Ensureno-unnecessary-boolean-literal-compareis enabled in your.eslintrcto catch issues during development:{ "rules": { "no-unnecessary-boolean-literal-compare": "error" } } -
Refactor Mercilessly
When reviewing code, scan for=== true/=== falsein conditionals—they’re almost always redundant.
Conclusion#
Fixing the “Unnecessary use of boolean literal” ESLint error is a quick win for cleaner, more readable code. By removing redundant comparisons, you’ll make your conditionals concise and easier to maintain. Remember: trust the boolean return values of array methods like includes() and some(), and let your code speak for itself without extra syntax.