Skip to content

@typescript-eslint/no-floating-promises warnings from new Promise-returning functions #12488

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Philipp91 opened this issue Dec 6, 2024 · 3 comments

Comments

@Philipp91
Copy link

I'm using React Router as a...

library

Reproduction

Use react-router v7, in particular with #11521 merged.

import {useNavigate} from 'react-router';
const navigate = useNavigate();
navigate(...);  // This line has an ESLint warning

System Info

System:
OS: Linux 6.11 Ubuntu 24.04.1 LTS 24.04.1 LTS (Noble Numbat)
CPU: (16) x64 AMD Ryzen 7 PRO 7840U w/ Radeon 780M Graphics
Memory: 41.37 GB / 58.56 GB
Container: Yes
Shell: 5.9 - /bin/zsh
Binaries:
Node: 22.3.0 - ~/.nvm/versions/node/v22.3.0/bin/node
Yarn: 1.22.22 - ~/.nvm/versions/node/v22.3.0/bin/yarn
npm: 10.9.0 - ~/.nvm/versions/node/v22.3.0/bin/npm
npmPackages:
react-router: ^7.0.2 => 7.0.2

Used Package Manager

npm

Expected Behavior

No ESLint warning.


Or the ability to silence the warning like I normally do, with .ignore() based on a global definition:

declare global {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    interface Promise<T> {
        ignore(): void;
    }
}

But that doesn't work because the signature returns void | Promise<void> and void.ignore() would be an error.

Actual Behavior

ESLint: Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator.(@typescript-eslint/ no-floating-promises)
@Philipp91 Philipp91 added the bug label Dec 6, 2024
@Philipp91
Copy link
Author

Would it make sense to switch to:

interface NavigateFunction {
    (to: To, options?: NavigateOptions): Promise<void>;
    (delta: number): Promise<void>;
}

@Philipp91
Copy link
Author

Another solution could be the "branded types" explained here.

interface NavigateFunction {
    (to: To, options?: NavigateOptions): void | (Promise<void> & { __linterBrands?: string });
    (delta: number): void | (Promise<void> & { __linterBrands?: string });
}

Haven't tested that though. I also considered augmenting the rule's config but I couldn't get a allowForKnownSafePromises config to work for some reason.

@timdorr
Copy link
Member

timdorr commented Dec 7, 2024

This is basically a duplicate of #12348, just a different effect of the change. I'll leave this open in case the solution there doesn't also solve this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants