redux-toolkit
redux-toolkit copied to clipboard
Unexpected no-floating-promises eslint error for MutationActionCreatorResult
We have the following code:
const [mutateSomething, { isLoading }] = api.useMutateSomethingMutation();
[...]
return (
<SomeComponent
onSomeEvent={() => {
mutateSomething(someArg);
}}
/>
);
Understandably, we're getting a @typescript-eslint/no-floating-promises error.
Based on this comment, we've therefore configured our eslintrc with the following:
'@typescript-eslint/no-floating-promises': [
'error',
{
allowForKnownSafePromises: [
{ from: 'package', name: 'SafePromise', package: '@reduxjs/toolkit' },
],
},
],
However, the eslint error isn't disappearing. Are we missing something, or does this just not work for this case for some reason?
Versions
- "@reduxjs/toolkit": "^2.2.6"
- "@typescript-eslint/eslint-plugin": "^7.13.1"
- "@typescript-eslint/parser": "^7.13.1"
- "eslint-plugin-react": "^7.34.3"
@Rovack Is this still an issue?
Yes, I just tried updating the dependencies and it doesn't look like anything's changed, with versions:
- "@reduxjs/toolkit": "2.5.0"
- "@typescript-eslint/eslint-plugin": "7.18.0"
- "@typescript-eslint/parser": "7.18.0"
- "eslint-plugin-react": "7.37.3"
Maybe you also need to add the RTKQ export?
'@typescript-eslint/no-floating-promises': [
'error',
{
allowForKnownSafePromises: [
{ from: 'package', name: 'SafePromise', package: '@reduxjs/toolkit' },
+ { from: 'package', name: 'SafePromise', package: '@reduxjs/toolkit/query' },
+ { from: 'package', name: 'SafePromise', package: '@reduxjs/toolkit/query/react' },
],
},
],
Unfortunately it still doesn't work with the addition of those lines. Not really sure how to debug why not.
I'm seeing this lint report on all Promises, too. Not sure if I'm setting things up wrong or what.
Minimal reproduction in https://github.com/typescript-eslint/examples/pull/20/files:
git clone https://github.com/typescript-eslint/examples
gh pr checkout 20
npm i
cd packages/redux-toolkit-floating-promises
npm run lint
.../index.ts
16:1 error 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
I tried downgrading from the latest @reduxjs/[email protected] to all the versions since #4102 was merged, including down to 2.2.0. Still the lint report.
@JoshuaKGoldberg did you also try to add the other two packages?
Ah, I did, I just neglected to check them in. Same issue. Added in https://github.com/typescript-eslint/examples/pull/20/commits/185fa5c6d3d9dfa6bcaa876f40195a36f0e348fe.
I did a bit of digging. The hover display for the type of store.dispatch(exampleThunk()) is:
Promise<PayloadAction<void, string, {
arg: void;
requestId: string;
requestStatus: "fulfilled";
}, never> | PayloadAction<unknown, string, {
arg: void;
requestId: string;
requestStatus: "rejected";
aborted: boolean;
condition: boolean;
} & ({
...;
} | ({
...;
} & {})), SerializedError>> & {
...;
} & {
...;
}
Ignoring deeper bits, that's a union of:
Promise< PayloadAction<...> >PayloadAction<...>{...}{...}
...so it makes sense the rule is reporting. The value might be a Promise. Even if we added PayloadAction to the allowForKnownSafePromises list, it might be a not-known-to-be-safe type.
Is store.dispatch() supposed to return a SafePromise, rather than a Promise?
It already does, that's the first intersection you're seeing.
https://github.com/reduxjs/redux-toolkit/blob/af3e75bb9e6a51e13603d2a5684ef3ba1da07e3b/packages/toolkit/src/createAsyncThunk.ts#L239
Promise<SuccessAction | FailureAction> & SafePromiseBrand & ExtraMethods