@typescript-eslint/no-unused-expressions

Disallow statements that compute a value and do nothing with it

warn by default

Also called typescript-eslint/no-unused-expressions, typescript/no-unused-expressions

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.

Configure#

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

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

Every option, set to its default:

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

Examples#

example.ts4 problems
declare const user: { name?: string; save(): void };

user.save;
user.name === "admin";
user?.name;
user.name!;
example.tsNo problems
declare const user: { name?: string; save(): void };

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

Options#

OptionDefaultWhat it does
allowShortCircuittrueAllow a && b(), a || b(), and a ?? b(), if the right side would be allowed as a statement.
allowTernarytrueAllow a ? b() : c(), if both branches would be allowed as statements.
allowTaggedTemplatesfalseAllow a tagged template such as sql`...` as a statement.
enforceForJSXfalseAlso report a JSX element as a statement.
ignoreDirectivesfalseAllow 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:

example.tsNo problems
declare const user: { save(): void } | undefined;

user && user.save();

The right side still needs to do something:

example.ts1 problem
declare const user: { save(): void } | undefined;

user && user.save;
example.tsNo problems
declare const user: { isNew: boolean; create(): void; update(): void };

user.isNew ? user.create() : user.update();
example.tswith { "allowShortCircuit": false, "allowTernary": false }2 problems
declare const user: { isNew: boolean; create(): void; update(): void } | undefined;

user && user.update();
user?.isNew ? user.create() : user?.update();
example.tswith { "allowTaggedTemplates": true }No problems
declare function sql(strings: TemplateStringsArray): void;

sql`DELETE FROM sessions`;
example.tsxwith { "enforceForJSX": true }1 problem
<p>Saved</p>;