Reputation: 121
The error itself:
(alias) deleteCategory(id: number): (dispatch: Dispatch<AnyAction>) => void
import deleteCategory
Argument of type '(dispatch: Dispatch) => void' is not assignable to parameter of type 'AnyAction'.
Property 'type' is missing in type '(dispatch: Dispatch) => void' but required in type 'AnyAction'.ts(2345)
Problematic code:
export function getCategoryList(
categories: CategoryType[],
dispatch: Dispatch
) {
return categories.map((category: CategoryType) => ({
...category,
onDelete: () => {
dispatch(deleteCategory(category._id)); //FIXME: Fix this. Error Appears here
},
}));
}
Implementation of deleteCategory:
export const deleteCategory = (id: number) => (dispatch: Dispatch) => {
deleteCategoryAPI(id)
.then(() => {
dispatch({
type: DELETE_CATEGORY,
category: id,
});
})
.catch((error) => console.error(error));
};
Implementation of deleteCategoryAPI:
export async function addCategoryAPI(category: CategoryType) {
return fetch(`${API_URL}/categories`, {
method: "POST",
body: JSON.stringify(category),
headers: { "Content-Type": "application/json; charset=UTF-8" },
}).then((response) => response.json());
}
I am using problematic code here:
const categoryList = getCategoryList(categoryState, dispatch);
...
return (
<List
dataSource={categoryList}
renderItem={({ name, onDelete }) => (
<List.Item>
<CategoryItem name={name} onDelete={onDelete} />
</List.Item>
)}
/>
);
function CategoryItem({ name, onDelete }: categoryItemPropsType) {
export type categoryItemPropsType = {
name: string;
onDelete: () => void;
};
What could be a problem? Spent several hours for that.
The interesting thing is that when I call dispatch(deleteCategory(category._id))
somewhere else in functional component e.g. it works without any problems.. Thank you very much!
Upvotes: 11
Views: 19633
Reputation: 111
I can initially think of a few different ways you could consider going about this depending on how much effort you feel like putting into it, how true to the vanilla implementation you'd like, and how accurate of typings you want.
The easiest implementation and truest to the API (but with poor typings):
// create your own dispatch function reference with custom typings
export const dispatchStore = store.dispatch as typeof store.dispatch | Dispatch<any>
// use custom typed dispatch (unfortunately, you can pass it almost `any`thing)
dispatchStore(myThunk('id123'))
An easy implementation but requires typing each call (and still has poor typings):
// optional
export const dispatchStore = store.dispatch
// type each dispatch as any (not good if you need to use 'abort', etc)
dispatchStore(myThunk('id123') as any)
This bullet is specific to Redux Toolkit but could easily apply to most TypeScript typing issues with third-party libraries (e.g. Redux). In the case of using redux-toolkit
, one could create a reference to either configureStore
or createSlice
and manipulate the typings as you choose. In the following code, I wrapped the createSlice function in createSlicePlus
, added a bunch of convenience logic behind the scenes, and enhanced the args and return types.
// convenience `request` wrapper around store `dispatch` that abstracts the rest
const promise = counter.request.decrementThunk(500)
// even the RTK thunk promise is typed appropriately
promise.abort()
The code for 3rd example can be found here on Github.
Upvotes: 5