---
url: /docs/guide/usage/linter/rules/typescript/no-unnecessary-condition.md
---

### What it does

Disallow conditions that are always truthy, always falsy, or always nullish
based on TypeScript's type information.

### Why is this bad?

Conditions with no possible runtime variation make code harder to read and can
hide logic errors. They often leave dead branches and suggest that the declared
types do not match the intended behavior.

### Examples

Examples of **incorrect** code for this rule:

```ts
declare const value: null;
if (value) {
  doWork();
}

const items: string[] = [];
if (items) {
  doWork();
}

declare const status: "ready";
if (!status) {
  reportError();
}
```

Examples of **correct** code for this rule:

```ts
declare const maybeUser: User | undefined;
if (maybeUser) {
  doWork(maybeUser);
}

const items: string[] = [];
if (items.length > 0) {
  doWork();
}

declare const status: "ready" | "";
if (!status) {
  reportError();
}
```

## Configuration

This rule accepts a configuration object with the following properties:

### allowConstantLoopConditions

type: `boolean | "never" | "always" | "only-allowed-literals"`

Represents the different ways `allowConstantLoopConditions` can be specified in JSON.
Can be:

* `true` or `false`
* A string enum (`"never"`, `"always"`, `"only-allowed-literals"`)

### checkTypePredicates

type: `boolean`

default: `false`

Whether to check arguments passed to type predicate and assertion functions.

When enabled, the rule reports a call if the argument already satisfies the predicate or
if an assertion function receives an argument that is always truthy or always falsy.

For example, `narrow(value)` is unnecessary because `value` already has type `true`:

```ts
declare const narrow: (value: unknown) => value is true;
const value = true;
if (narrow(value)) {
  // ...
}
```

## How to use

## Version

This rule was added in v1.48.0.

## References
