@typescript-eslint/no-confusing-void-expression

Require expressions of type void to stand alone as statements

fixableneeds types

Also called typescript-eslint/no-confusing-void-expression, typescript/no-confusing-void-expression

A function that returns void has no result to use. Code like const saved = save(user) or return log(error) suggests there is one, and the reader goes looking for a value that doesn't exist. A void call belongs on its own line.

A void call is still fine on the right of &&, || and ??, and in the branches of ? :, if the whole expression is a statement.

--fix adds braces to an arrow function, and takes the call out of a return. A void value that's assigned or passed on is reported but not fixed.

Configure#

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

bunfig.toml
[lint.rules]
"@typescript-eslint/no-confusing-void-expression" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"@typescript-eslint/no-confusing-void-expression" = ["error", {
  ignoreArrowShorthand = false,
  ignoreVoidOperator = false,
  ignoreVoidReturningFunctions = false,
}]

Examples#

example.ts3 problems
declare function log(message: string): void;

const result = log("saved");

const onSave = () => log("saved");

function onError(error: Error) {
  return log(error.message);
}
example.tsNo problems
declare function log(message: string): void;
declare const verbose: boolean;

log("saved");
verbose && log("details");

const onSave = () => {
  log("saved");
};

function onError(error: Error) {
  log(error.message);
}

Options#

OptionDefaultWhat it does
ignoreArrowShorthandfalseAllow () => log(), an arrow function without braces.
ignoreVoidOperatorfalseAllow a void expression anywhere if it's marked with the void operator. --fix then adds void in arrow functions and returns.
ignoreVoidReturningFunctionsfalseAllow returning a void expression from a function that returns void itself.
example.tswith { "ignoreArrowShorthand": true }No problems
declare function log(message: string): void;

["a", "b"].forEach(name => log(name));

With ignoreVoidOperator:

example.tswith { "ignoreVoidOperator": true }No problems
declare function log(message: string): void;

const onSave = () => void log("saved");
example.tswith { "ignoreVoidOperator": true }1 problem
declare function log(message: string): void;

const onSave = () => log("saved");

With ignoreVoidReturningFunctions, the return type can be written on the function or come from where the function is used:

example.tswith { "ignoreVoidReturningFunctions": true }No problems
declare function log(message: string): void;

function onError(error: Error): void {
  return log(error.message);
}

["a", "b"].forEach(name => log(name));
example.tswith { "ignoreVoidReturningFunctions": true }1 problem
declare function log(message: string): void;

function onError(error: Error) {
  return log(error.message);
}