@typescript-eslint/no-floating-promises

Require promises to be awaited, returned, or handled

has suggestionsneeds types

Also called typescript-eslint/no-floating-promises, typescript/no-floating-promises

A promise that nobody awaits runs on its own. If it rejects, the try around the call doesn't catch the error, and the code after it runs before the work is done.

A promise counts as handled if it's awaited, returned, given a .catch() or a second argument to .then(), or marked as ignored on purpose with void.

bun lint --type-aware turns this rule on in TypeScript files.

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-floating-promises" = "error" # or "warn"

Every option, set to its default:

bunfig.toml
[lint.rules]
"@typescript-eslint/no-floating-promises" = ["error", {
  ignoreVoid = true,
  ignoreIIFE = false,
  checkThenables = false,
  allowForKnownSafePromises = [], # list of strings or objects
  allowForKnownSafeCalls = [], # list of strings or objects
}]

Examples#

example.ts1 problem
async function save(data: string): Promise<void> {}

function onClick() {
  save("draft");
}
example.tsNo problems
async function save(data: string): Promise<void> {}

async function onClick() {
  await save("draft");
}

function onBlur() {
  void save("draft");
}

Options#

OptionDefaultWhat it does
ignoreVoidtrueAllow void promise as a way to say "ignored on purpose".
ignoreIIFEfalseAllow an async function that's called where it's written: (async () => { ... })().
checkThenablesfalseAlso report objects that only have a then method.
allowForKnownSafePromises[]Promise types that never need handling.
allowForKnownSafeCalls[]Functions that return promises you never need to handle.

With ignoreVoid set to false, this is reported:

example.tswith { "ignoreVoid": false }1 problem
async function save(data: string): Promise<void> {}

void save("draft");

An entry in allowForKnownSafePromises or allowForKnownSafeCalls is a name, or an object that also says where the name is declared:

EntryWhat it matches
"SafePromise"Anything with that name.
{ "from": "file", "name": "SafePromise" }A name declared in your project.
{ "from": "lib", "name": "PromiseLike" }A name from the built-in TypeScript types.
{ "from": "package", "name": "track", "package": "analytics" }A name from a package.

With { "from": "file", "name": "SafePromise" } in allowForKnownSafePromises, this isn't reported:

example.tswith { "allowForKnownSafePromises": [{ "from": "file", "name": "SafePromise" }] }No problems
type SafePromise = Promise<void> & { neverRejects: true };

declare function log(message: string): SafePromise;

log("saved");

With { "from": "file", "name": "schedule" } in allowForKnownSafeCalls, neither is this:

example.tswith { "allowForKnownSafeCalls": [{ "from": "file", "name": "schedule" }] }No problems
declare function schedule(job: () => void): Promise<void>;

schedule(() => console.log("tick"));