# @typescript-eslint/no-unused-expressions

> Disallow statements that compute a value and do nothing with it

A statement such as `user.name;` or `count + 1;` computes a value and throws it away. It's usually a mistake, like a call without its `()`, a `===` that was meant to be `=`, or a line left behind after an edit.

Calls, `new`, assignments, `await`, `delete`, `void`, `import()`, and directives such as `"use strict"` do something, so they aren't reported. Neither are `user && user.save();` and `user.isNew ? user.create() : user.update();`, which are short ways to write an `if`. The rule looks through `as`, `!`, and type arguments, so `save as unknown;` is reported like `save;`.

This rule is on by default in TypeScript files.

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

## Configure

On by default as a warning. To turn it off:

```toml bunfig.toml
[lint.rules]
"@typescript-eslint/no-unused-expressions" = "off" # or "error"
```

Every option, set to its default:

```toml bunfig.toml
[lint.rules]
"@typescript-eslint/no-unused-expressions" = ["warn", {
  allowShortCircuit = true,
  allowTernary = true,
  allowTaggedTemplates = false,
  enforceForJSX = false,
  ignoreDirectives = false,
}]
```

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

## Examples

Reported:

{/* bad {"count": 4} */}
```ts
declare const user: { name?: string; save(): void };

user.save;
user.name === "admin";
user?.name;
user.name!;
```

Not reported:

{/* good */}
```ts
declare const user: { name?: string; save(): void };

user.save();
user.name = "admin";
user?.save();
```

## Options

| Option | Default | What it does |
| --- | --- | --- |
| `allowShortCircuit` | `true` | Allow `a && b()`, `a \|\| b()`, and `a ?? b()`, if the right side would be allowed as a statement. |
| `allowTernary` | `true` | Allow `a ? b() : c()`, if both branches would be allowed as statements. |
| `allowTaggedTemplates` | `false` | Allow a tagged template such as `` sql`...` `` as a statement. |
| `enforceForJSX` | `false` | Also report a JSX element as a statement. |
| `ignoreDirectives` | `false` | Allow strings at the start of a file or a function when `ecmaVersion` is 3, which has no directives. |

With an ESLint config file the defaults are typescript-eslint's: every option is `false`.

By default, you can use `&&` instead of an `if`:

{/* good */}
```ts
declare const user: { save(): void } | undefined;

user && user.save();
```

The right side still needs to do something:

{/* bad */}
```ts
declare const user: { save(): void } | undefined;

user && user.save;
```

{/* good */}
```ts
declare const user: { isNew: boolean; create(): void; update(): void };

user.isNew ? user.create() : user.update();
```

{/* bad {"options": [{"allowShortCircuit": false, "allowTernary": false}], "count": 2} */}
```ts
declare const user: { isNew: boolean; create(): void; update(): void } | undefined;

user && user.update();
user?.isNew ? user.create() : user?.update();
```

{/* good {"options": [{"allowTaggedTemplates": true}]} */}
```ts
declare function sql(strings: TemplateStringsArray): void;

sql`DELETE FROM sessions`;
```

{/* bad {"options": [{"enforceForJSX": true}]} */}
```tsx
<p>Saved</p>;
```
