# @typescript-eslint/strict-boolean-expressions

> Disallow nullable numbers, strings, and booleans, `any`, and always-true values in conditions

`if (count)` on a `number | undefined` is false for `undefined`, and also for `0` and `NaN`. `if (name)` on an optional string is also false for `""`. Code that means "was it given?" then skips a valid value.

This rule checks the conditions of `if`, `while`, `do`, `for`, and `? :`, the operand of `!`, the left side of `&&` and `||`, and the return value of callbacks passed to `filter`, `find`, `some`, `every`, and similar array methods.

By default a condition can be a `boolean`, a `string`, a `number`, or an object that can be `null` or `undefined`. These are reported:

- a `boolean`, `string`, `number`, or enum that can also be `null` or `undefined`
- `any` and `unknown`
- a mix such as `string | number`
- an object that's never nullish, which is always true
- a value that's always nullish, which is always false

This rule needs `strictNullChecks` (or `strict`) in your `tsconfig.json`.

{/* Generated by src/codegen/lint-rule-docs.ts. Do not edit this section. */}

## Configure

Off by default. This rule needs types, so turning it on makes `bun lint` type check your code first.

```toml bunfig.toml
[lint.rules]
"@typescript-eslint/strict-boolean-expressions" = "error" # or "warn"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"@typescript-eslint/strict-boolean-expressions" = ["error", {
  allowString = true,
  allowNumber = true,
  allowNullableObject = true,
  allowNullableBoolean = false,
  allowNullableString = false,
  allowNullableNumber = false,
  allowNullableEnum = false,
  allowAny = false,
  allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing = false,
}]
```

{/* End of the generated section. */}

## Examples

Reported:

{/* bad {"count": 3} */}
```ts
function render(width?: number, title?: string, items: string[] = []) {
  if (width) {
    resize(width); // skipped for 0
  }
  const heading = title || "Untitled"; // replaces ""
  if (items) {
    draw(items); // always runs, even for []
  }
}

declare function resize(width: number): void;
declare function draw(items: string[]): void;
```

Not reported:

{/* good */}
```ts
function render(width?: number, title?: string, items: string[] = []) {
  if (width !== undefined) {
    resize(width);
  }
  const heading = title ?? "Untitled";
  if (items.length > 0) {
    draw(items);
  }
}

declare function resize(width: number): void;
declare function draw(items: string[]): void;
```

Array method callbacks, `unknown`, and mixed types are reported too:

{/* bad {"count": 3} */}
```ts
function pick(sizes: (number | undefined)[], raw: unknown, id: string | number) {
  const known = sizes.filter(size => size); // drops 0 too
  if (raw) console.log(raw);
  if (id) console.log(id);
}
```

A nullable object has only one falsy case, so it's allowed:

{/* good */}
```ts
function nameOf(user?: { name: string }) {
  return user ? user.name : "guest";
}
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `allowString` | `true` | Allow `string`. |
| `allowNumber` | `true` | Allow `number` and `bigint`. |
| `allowNullableObject` | `true` | Allow an object, function, or symbol that can be nullish. |
| `allowNullableBoolean` | `false` | Allow `boolean \| null \| undefined`. |
| `allowNullableString` | `false` | Allow `string \| null \| undefined`. |
| `allowNullableNumber` | `false` | Allow `number \| null \| undefined`. |
| `allowNullableEnum` | `false` | Allow an enum that can be nullish. |
| `allowAny` | `false` | Allow `any` and `unknown`. |
| `allowRuleToRunWithoutStrictNullChecksIKnowWhatIAmDoing` | `false` | Don't report a project that has `strictNullChecks` off. Without it TypeScript hides `null` and `undefined` from types, so the rule misses most cases. |

Turn off `allowString` and `allowNumber` to accept only real booleans and nullable objects. These are then reported:

{/* bad {"count": 2, "options": [{"allowString": false, "allowNumber": false}]} */}
```ts
function summary(items: string[], query: string) {
  if (items.length) {
    console.log(items.length);
  }
  return query ? `Results for ${query}` : "All";
}
```

An optional flag is a common case to allow. Use `allowNullableBoolean` for that:

{/* good {"options": [{"allowNullableBoolean": true}]} */}
```ts
function build(options: { minify?: boolean }) {
  if (options.minify) {
    console.log("minifying");
  }
}
```

## When not to use it

In a codebase that relies on truthiness checks, this rule reports a lot of code that works. Start with the `allowNullable` options on, or leave it off.
