tags | level | |||
---|---|---|---|---|
|
warn |
Enforce Explicit Value Comparisons
Detects shorthand value usage patterns (implicit truthiness/falsiness checking) in JavaScript/TypeScript code. This rule helps identify places where explicit comparisons might be preferred for clarity and type safety. Common cases include checking for undefined/null, empty strings, zero values, and boolean states.
engine marzano(0.1)
language js
or {
// If statements with implicit boolean conversion
`if ($condition) $body` where {
$condition <: identifier()
},
// While loops with implicit boolean conversion
`while ($condition) $body` where {
$condition <: identifier()
},
// Do-while loops with implicit boolean conversion
`do $body while ($condition)` where {
$condition <: identifier()
},
// Logical AND/OR with identifier (handles both left and right positions)
`$left && $right` where {
or {
$left <: identifier(),
$right <: identifier()
}
},
`$left || $right` where {
or {
$left <: identifier(),
$right <: identifier()
}
},
// Ternary operator condition
`$condition ? $true_expr : $false_expr` where {
$condition <: identifier()
},
// Negation of identifier
`!$variable` where {
$variable <: identifier()
}
}
This rule does not provide auto-fixes because:
- No type information: GritQL operates at the AST level without access to TypeScript type information
- Semantic ambiguity: Converting
if (value)
requires different fixes based on the intended type:- For booleans:
if (value === true)
orif (value !== false)
- For strings:
if (value !== undefined)
orif (value.length > 0)
- For numbers:
if (value !== 0)
orif (!isNaN(value))
- For arrays:
if (value.length > 0)
orif (value !== undefined)
- For objects:
if (value !== null)
orif (value !== undefined)
- For booleans:
- Context dependency: The correct fix depends on what falsy values should be considered valid vs invalid
// Detected: Boolean variables in if statements
if (isEnabled) {
doSomething();
}
// Detected: String variables (could be undefined/empty)
if (userName) {
greetUser();
}
// Detected: Number variables (could be 0)
if (count) {
processItems();
}
// Detected: While loops
while (isRunning) {
process();
}
// Detected: Do-while loops
do {
work();
} while (hasMore);
// Detected: Logical operations
isReady && execute();
hasPermission || showError();
// Detected: Ternary operators
const result = isSuccess ? "OK" : "Error";
// Detected: Negation
if (!isDisabled) {
run();
}
When this rule flags an issue, consider the variable type and intended behavior:
// Instead of:
if (isEnabled) { ... }
// Consider:
if (isEnabled === true) { ... }
if (isEnabled !== false) { ... }
// Instead of:
if (userName) { ... }
// Consider:
if (userName !== undefined) { ... }
if (userName !== '') { ... }
if (userName?.length > 0) { ... }
// Instead of:
if (count) { ... }
// Consider:
if (count > 0) { ... }
if (count !== 0) { ... }
if (count !== undefined) { ... }
// Instead of:
const result = isSuccess ? "OK" : "Error";
// Consider:
const result = isSuccess === true ? "OK" : "Error";
const result = isSuccess !== false ? "OK" : "Error";
// Instead of:
while (hasItems) { ... }
do { ... } while (hasMore);
// Consider:
while (hasItems === true) { ... }
do { ... } while (hasMore !== false);
- This rule helps maintain coding style consistency and type safety
- Manual review is required to determine the appropriate explicit comparison
- Consider what falsy values should be treated as valid vs invalid
- Common falsy values:
false
,0
,""
,null
,undefined
,NaN