@typescript-eslint/no-unused-expressions
Disallow statements that compute a value and do nothing with it
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:
[lint.rules]
"@typescript-eslint/no-unused-expressions" = "off" # or "error"Every option, set to its default:
[lint.rules]
"@typescript-eslint/no-unused-expressions" = ["warn", {
allowShortCircuit = true,
allowTernary = true,
allowTaggedTemplates = false,
enforceForJSX = false,
ignoreDirectives = false,
}]Examples#
declare const user: { name?: string; save(): void };
user.save;Expected an assignment or function call and instead saw an expression.
user.name === "admin";Expected an assignment or function call and instead saw an expression.
user?.name;Expected an assignment or function call and instead saw an expression.
user.name!;Expected an assignment or function call and instead saw an expression.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:
declare const user: { save(): void } | undefined;
user && user.save();The right side still needs to do something:
declare const user: { save(): void } | undefined;
user && user.save;Expected an assignment or function call and instead saw an expression.declare const user: { isNew: boolean; create(): void; update(): void };
user.isNew ? user.create() : user.update();{ "allowShortCircuit": false, "allowTernary": false }2 problemsdeclare const user: { isNew: boolean; create(): void; update(): void } | undefined;
user && user.update();Expected an assignment or function call and instead saw an expression.
user?.isNew ? user.create() : user?.update();Expected an assignment or function call and instead saw an expression.{ "allowTaggedTemplates": true }No problemsdeclare function sql(strings: TemplateStringsArray): void;
sql`DELETE FROM sessions`;{ "enforceForJSX": true }1 problem<p>Saved</p>;Expected an assignment or function call and instead saw an expression.