no-confusing-void-expression
Require expressions of type void to appear in statement position.
Extending "plugin:@typescript-eslint/strict-type-checked"
in an ESLint configuration enables this rule.
Some problems reported by this rule are automatically fixable by the --fix
ESLint command line option.
Some problems reported by this rule are manually fixable by editor suggestions.
This rule requires type information to run.
void
in TypeScript refers to a function return that is meant to be ignored.
Attempting to use a void
-typed value, such as storing the result of a called function in a variable, is often a sign of a programmer error.
void
can also be misleading for other developers even if used correctly.
This rule prevents void
type expressions from being used in misleading locations such as being assigned to a variable, provided as a function argument, or returned from a function.
- Flat Config
- Legacy Config
export default tseslint.config({
rules: {
"@typescript-eslint/no-confusing-void-expression": "error"
}
});
module.exports = {
"rules": {
"@typescript-eslint/no-confusing-void-expression": "error"
}
};
Try this rule in the playground ↗
Examples
- ❌ Incorrect
- ✅ Correct
// somebody forgot that `alert` doesn't return anything
const response = alert('Are you sure?');
console.log(alert('Are you sure?'));
// it's not obvious whether the chained promise will contain the response (fixable)
promise.then(value => window.postMessage(value));
// it looks like we are returning the result of `console.error` (fixable)
function doSomething() {
if (!somethingToDo) {
return console.error('Nothing to do!');
}
console.log('Doing a thing...');
}
Open in Playground// just a regular void function in a statement position
alert('Hello, world!');
// this function returns a boolean value so it's ok
const response = confirm('Are you sure?');
console.log(confirm('Are you sure?'));
// now it's obvious that `postMessage` doesn't return any response
promise.then(value => {
window.postMessage(value);
});
// now it's explicit that we want to log the error and return early
function doSomething() {
if (!somethingToDo) {
console.error('Nothing to do!');
return;
}
console.log('Doing a thing...');
}
// using logical expressions for their side effects is fine
cond && console.log('true');
cond || console.error('false');
cond ? console.log('true') : console.error('false');
Open in PlaygroundOptions
This rule accepts the following options:
type Options = [
{
/** Whether to ignore "shorthand" `() =>` arrow functions: those without `{ ... }` braces. */
ignoreArrowShorthand?: boolean;
/** Whether to ignore returns that start with the `void` operator. */
ignoreVoidOperator?: boolean;
/** Whether to ignore returns from functions with explicit `void` return types and functions with contextual `void` return types. */
ignoreVoidReturningFunctions?: boolean;
},
];
const defaultOptions: Options = [
{
ignoreArrowShorthand: false,
ignoreVoidOperator: false,
ignoreVoidReturningFunctions: false,
},
];
ignoreArrowShorthand
Whether to ignore "shorthand" () =>
arrow functions: those without { ... }
braces. Default: false
.
Whether to ignore "shorthand" () =>
arrow functions: those without { ... }
braces.
It might be undesirable to wrap every arrow function shorthand expression. Especially when using the Prettier formatter, which spreads such code across 3 lines instead of 1.
Examples of additional correct code with this option enabled:
promise.then(value => window.postMessage(value));
Open in PlaygroundignoreVoidOperator
Whether to ignore returns that start with the void
operator. Default: false
.
Whether to ignore returns that start with the void
operator.
It might be preferable to only use some distinct syntax
to explicitly mark the confusing but valid usage of void expressions.
This option allows void expressions which are explicitly wrapped in the void
operator.
This can help avoid confusion among other developers as long as they are made aware of this code style.
This option also changes the automatic fixes for common cases to use the void
operator.
It also enables a suggestion fix to wrap the void expression with void
operator for every problem reported.
Examples of additional correct code with this option enabled:
// now it's obvious that we don't expect any response
promise.then(value => void window.postMessage(value));
// now it's explicit that we don't want to return anything
function doSomething() {
if (!somethingToDo) {
return void console.error('Nothing to do!');
}
console.log('Doing a thing...');
}
// we are sure that we want to always log `undefined`
console.log(void alert('Hello, world!'));
Open in PlaygroundignoreVoidReturningFunctions
Whether to ignore returns from functions with explicit void
return types and functions with contextual void
return types. Default: false
.
Whether to ignore returns from functions with void
return types when inside a function with a void
return type.
Some projects prefer allowing functions that explicitly return void
to return void
expressions. Doing so allows more writing more succinct functions.
This is technically risky as the void
-returning function might actually be returning a value not seen by the type system.
function foo(): void {
return console.log();
}
function onError(callback: () => void): void {
callback();
}
onError(() => console.log('oops'));
Open in PlaygroundWhen Not To Use It
The return type of a function can be inspected by going to its definition or hovering over it in an IDE.
If you don't care about being explicit about the void type in actual code then don't use this rule.
Also, if you strongly prefer a concise coding style more strongly than any fear of void
-related bugs then you can avoid this rule.
Type checked lint rules are more powerful than traditional lint rules, but also require configuring type checked linting.
See Troubleshooting > Linting with Type Information > Performance if you experience performance degradations after enabling type checked rules.