redux-toolkit
redux-toolkit copied to clipboard
TS error on injected API optimistic update
Hi, I'm getting a TS error when I try to use optimistic updates on a code-split API instance. The thunk works correctly and updates the data correctly, but TypeScript isn't happy. Here's the thunk:
const dispatch = useAppDispatch();
...
dispatch(
beneficiariesApi.util.updateQueryData(
'getBeneficiary',
beneficiaryId,
(draft) => {
draft.data.attributes.trusted = true;
return draft;
}
)
);
TS error:
No overload matches this call.
The last overload gave the following error.
Argument of type 'ThunkAction<PatchCollection, RootState<UpdateDefinitions<{ getCountries: QueryDefinition<void, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, "ReferenceData", CountryPage, "api">; getCurrencies: QueryDefinition<...>; }, "ReferenceData" | ... 1 more ... | "Beneficiary", never> ...' is not assignable to parameter of type 'UnknownAction'.ts(2769)
I'm not sure what I'm doing wrong, as this endpoint is definitely defined within this set of endpoints.
I see that you have set up a useAppDispatch hook per our recommendations. What is the TS-inferred type of dispatch at that point? Also, what does your store configuration look like?
Hi, the inferred type is:
(property) updateQueryData: <"getBeneficiary">(endpointName: "getBeneficiary", args: string, updateRecipe: Recipe<Beneficiary>, updateProvided?: boolean) => ThunkAction<PatchCollection, RootState<...>, any, UnknownAction>
The store config is:
import { configureStore } from '@reduxjs/toolkit';
// Or from '@reduxjs/toolkit/query/react'
import { setupListeners } from '@reduxjs/toolkit/query';
import { api } from './services/api';
import { registrationApi } from './services/registration';
export const store = configureStore({
reducer: {
// Add the generated reducer as a specific top-level slice
[api.reducerPath]: api.reducer,
[registrationApi.reducerPath]: registrationApi.reducer,
},
// Adding the api middleware enables caching, invalidation, polling,
// and other useful features of `rtk-query`.
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat([api.middleware, registrationApi.middleware]),
});
// Infer the `RootState` and `AppDispatch` types from the store itself
export type RootState = ReturnType<typeof store.getState>;
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
export type AppDispatch = typeof store.dispatch;
// optional, but required for refetchOnFocus/refetchOnReconnect behaviors
// see `setupListeners` docs - takes an optional callback as the 2nd arg for customization
setupListeners(store.dispatch);
And the beneficiariesApi is injected as:
import { api } from './api';
export const beneficiariesApi = api
.enhanceEndpoints({
addTagTypes: ['Beneficiaries', 'Beneficiary'],
})
.injectEndpoints({
endpoints: (build) => ({
... endpoint definitions
Hope that helps :)
Sorry, to clarify, what is the type of the dispatch function variable, and the AppDispatch type? Are they the same inferred type? Does the inferred type include a mention of "thunks" at all?
dispatch:
const dispatch: ThunkDispatch<{
api: CombinedState<{
getCountries: QueryDefinition<void, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, "ReferenceData", CountryPage, "api">;
getCurrencies: QueryDefinition<...>;
}, "ReferenceData", "api">;
registrationApi: CombinedState<...>;
}, undefined, UnknownAction> & Dispatch<...>
AppDispatch:
type AppDispatch = ThunkDispatch<{
api: CombinedState<{
getCountries: QueryDefinition<void, BaseQueryFn<string | FetchArgs, unknown, FetchBaseQueryError, {}, FetchBaseQueryMeta>, "ReferenceData", CountryPage, "api">;
getCurrencies: QueryDefinition<...>;
}, "ReferenceData", "api">;
registrationApi: CombinedState<...>;
}, undefined, UnknownAction> & Dispatch<...>
Ah, it seems it doesn't have the injected endpoints
Yeah, the API slice TS types only know about the endpoints in the original definition. someApi.injectEndpoints() then returns the same runtime object but with the additional TS types applied.
That said, the original error sounds more like "this typed version of dispatch doesn't know about thunks at all", but the inferred type does know about thunks, so I'm confused.
Not sure there's anything else we can do here without a repro.