strict-boolean-expressions
Disallow certain types in boolean expressions.
Some problems reported by this rule are manually fixable by editorsuggestions.
This rule requirestype information to run, which comes with performance tradeoffs.
Forbids usage of non-boolean types in expressions where a boolean is expected.boolean andnever types are always allowed.Additional types which are considered safe in a boolean context can be configured via options.
The following nodes are considered boolean expressions and their type is checked:
- Argument to the logical negation operator (
!arg). - The condition in a conditional expression (
cond ? x : y). - Conditions for
if,for,while, anddo-whilestatements. - Operands of logical binary operators (
lhs || rhsandlhs && rhs).- Right-hand side operand is ignored when it's not a descendant of another boolean expression.This is to allow usage of boolean operators for their short-circuiting behavior.
- Asserted argument of an assertion function (
assert(arg)). - Return type of array predicate functions such as
filter(),some(), etc.
- Flat Config
- Legacy Config
exportdefault tseslint.config({
rules:{
"@typescript-eslint/strict-boolean-expressions":"error"
}
});
module.exports={
"rules":{
"@typescript-eslint/strict-boolean-expressions":"error"
}
};
Try this rule in the playground ↗
Examples
- ❌ Incorrect
- ✅ Correct
// nullable numbers are considered unsafe by default
declareconst num:number|undefined;
if(num){
console.log('num is defined');
}
// nullable strings are considered unsafe by default
declareconst str:string|null;
if(!str){
console.log('str is empty');
}
// nullable booleans are considered unsafe by default
functionfoo(bool?:boolean){
if(bool){
bar();
}
}
// `any`, unconstrained generics and unions of more than one primitive type are disallowed
const foo=<T>(arg:T)=>(arg?1:0);
// always-truthy and always-falsy types are disallowed
let obj={};
while(obj){
obj=getObj();
}
// assertion functions without an `is` are boolean contexts.
declarefunctionassert(value:unknown):asserts value;
let maybeString= Math.random()>0.5?'':undefined;
assert(maybeString);
// array predicates' return types are boolean contexts.
['one',null].filter(x=> x);
Open in Playground// nullable values should be checked explicitly against null or undefined
let num:number|undefined=0;
if(num!=null){
console.log('num is defined');
}
let str:string|null=null;
if(str!=null&&!str){
console.log('str is empty');
}
functionfoo(bool?:boolean){
if(bool??false){
bar();
}
}
// `any` types should be converted to boolean explicitly
constfoo=(arg:any)=>(Boolean(arg)?1:0);
Open in PlaygroundOptions
This rule accepts the following options:
typeOptions=[
{
/** Whether to allow `any`s in a boolean context. */
allowAny?:boolean;
/** Whether to allow nullable `boolean`s in a boolean context. */
allowNullableBoolean?:boolean;
/** Whether to allow nullable `enum`s in a boolean context. */
allowNullableEnum?:boolean;
/** Whether to allow nullable `number`s in a boolean context. */
allowNullableNumber?:boolean;
/** Whether to allow nullable `object`s, `symbol`s, and functions in a boolean context. */
allowNullableObject?:boolean;
/** Whether to allow nullable `string`s in a boolean context. */
allowNullableString?:boolean;
/** Whether to allow `number`s in a boolean context. */
allowNumber?:boolean;
/** Unless this is set to `true`, the rule will error on every file whose `tsconfig.json` does _not_ have the `strictNullChecks` compiler option (or `strict`) set to `true`. */
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing?:boolean;
/** Whether to allow `string`s in a boolean context. */
allowString?:boolean;
},
];
const defaultOptions: Options=[
{
allowAny:false,
allowNullableBoolean:false,
allowNullableEnum:false,
allowNullableNumber:false,
allowNullableObject:true,
allowNullableString:false,
allowNumber:true,
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing:false,
allowString:true,
},
];
allowString
Whether to allowstrings in a boolean context. Default:true.
This can be safe because strings have only one falsy value ("").Set this tofalse if you prefer the explicitstr != "" orstr.length > 0 style.
allowNumber
Whether to allownumbers in a boolean context. Default:true.
This can be safe because numbers have only two falsy values (0 andNaN).Set this tofalse if you prefer the explicitnum != 0 and!Number.isNaN(num) style.
allowNullableObject
Whether to allow nullableobjects,symbols, and functions in a boolean context. Default:true.
This can be safe because objects, functions, and symbols don't have falsy values.Set this tofalse if you prefer the explicitobj != null style.
allowNullableBoolean
Whether to allow nullablebooleans in a boolean context. Default:false.
This is unsafe because nullable booleans can be eitherfalse or nullish.Set this tofalse if you want to enforce explicitbool ?? false orbool ?? true style.Set this totrue if you don't mind implicitly treating false the same as a nullish value.
allowNullableString
Whether to allow nullablestrings in a boolean context. Default:false.
This is unsafe because nullable strings can be either an empty string or nullish.Set this totrue if you don't mind implicitly treating an empty string the same as a nullish value.
allowNullableNumber
Whether to allow nullablenumbers in a boolean context. Default:false.
This is unsafe because nullable numbers can be either a falsy number or nullish.Set this totrue if you don't mind implicitly treating zero or NaN the same as a nullish value.
allowNullableEnum
Whether to allow nullableenums in a boolean context. Default:false.
This is unsafe because nullable enums can be either a falsy number or nullish.Set this totrue if you don't mind implicitly treating an enum whose value is zero the same as a nullish value.
allowAny
Whether to allowanys in a boolean context. Default:false.
This is unsafe for becauseany allows any values and disables many type checking checks.Set this totrue at your own risk.
allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing
Unless this is set totrue, the rule will error on every file whosetsconfig.json doesnot have thestrictNullChecks compiler option (orstrict) set totrue. Default:false.
This option will be removed in the next major version of typescript-eslint.
If this is set tofalse, then the rule will error on every file whosetsconfig.json doesnot have thestrictNullChecks compiler option (orstrict) set totrue.
WithoutstrictNullChecks, TypeScript essentially erasesundefined andnull from the types. This means when this rule inspects the types from a variable,it will not be able to tell that the variable might benull orundefined, which essentially makes this rule a lot less useful.
You should be usingstrictNullChecks to ensure complete type-safety in your codebase.
If for some reason you cannot turn onstrictNullChecks, but still want to use this rule - you can use this option to allow it - but know that the behavior of this rule isundefined with the compiler option turned off. We will not accept bug reports if you are using this option.
When Not To Use It
If your project isn't likely to experience bugs from falsy non-boolean values being used in logical conditions, you can skip enabling this rule.
Otherwise, this rule can be quite strict around requiring exact comparisons in logical checks.If you prefer more succinct checks over more precise boolean logic, this rule might not be for you.
Related To
- no-unnecessary-condition - Similar rule which reports always-truthy and always-falsy values in conditions
Type checked lint rules are more powerful than traditional lint rules, but also require configuringtype checked linting.
SeeTroubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.