typescriptmiddlewareredux-toolkitredux-middleware

Typescript: how to type a custom redux middleware that handles async actions


I hope everyone is doing great this weekend!

disclaimer: I already researched the whole day and I am coming to ask for help only after I tried many things, I opened more than 20 StackOverflow links and read through them...

I have this custom redux middleware that serves the purpose of capturing promises that fail and dispatches an action for each.

const errorMiddleware: Middleware =
  ({ dispatch }: MiddlewareAPI) =>
  (next: Dispatch) =>
  async (action: AnyAction) => {
    const { meta, payload } = action;
    const { withErrorHandler, defaultErrorCode } = meta;

    const isPromise = getIsPromise(payload);

    if (isPromise && withErrorHandler) {
      return next(action)
        .catch(errorHandler(defaultErrorCode))
        .catch((handledError: ISystemError) =>
          Promise.reject(
            handledError.shouldSkipHandleError
              ? handledError
              : dispatch(addError(handledError))
          )
        );
    }

    return next(action);
  };

the problem I am trying to solve is the async (action: AnyAction) => {

I get an error message saying

Argument of type 'AsyncThunkAction<number, number, {}>' is not assignable to parameter of type 'AnyAction'.
  Property 'type' is missing in type 'AsyncThunkAction<number, number, {}>' but required in type 'AnyAction'.  TS2345

    53 |         <button
    54 |           className={styles.asyncButton}
  > 55 |           onClick={() => dispatch(incrementAsync(incrementValue))}
       |                                   ^
    56 |         >
    57 |           Add Async
    58 |         </button>

this is because incrementAsync uses createAsyncThunk from '@reduxjs/toolkit';

export const incrementAsync = createAsyncThunk(
  'counter/fetchCount',
  async (amount: number) => {
    const response = await fetchCount(amount);
    // The value we return becomes the `fulfilled` action payload
    return response.data;
  }
);

So I believe I need to change the last function ``async (action: AnyAction) => {` type of action to something else, but I can't figure it out, may I have the enlightenment of your words?

here is a link for the typescript playground if it helps

https://www.typescriptlang.org/play?#code/PTAEEsFsAcHsCcAuoDeoCCA7AnugxouLJqAL6gBm8skoARPAKYAmArgB50BQUcSqoAOaNk5KjXoAbWMwCGAZwAWdANw8YCZGjxNZiRunnZMeACqLWmANYAaUDsZ7GAZUng8jOwAVZ2abOZ8QmIySmpaAHIAASY2dgAreWBEWFhJK3BECLUudT4tLlAMIxNzSysgokwbQtAAEXB5aD08RRqigFlwZmZJRgB3WSZ20DLrBqaWttqunr7BpnQvAEkRrFwCKpGQItAfP1gAyuIasXD6GJYOROTU9MzVXLxieWRhRGX5L3DGxlAAXlAAApmgcAgAuUDlTCwfqYACUAIAfLUAISo94g3z+Zh2OiIRSMTB0REAH1JoHRmNBOLx0B+8kYADoCUSSTlnphXqBGPBqPAABKyTC9XkA4HNeCySCQ17wcCYQSI-5I1CkXIK-TwCiyDygZbObCvRiQACifIQqFqRX0r1liHlirUu1ASlgrEkzGcGWgQpFfXN-MhOskjLU6q4nO5AWYgctgKBvKDoGF2GVqqBKFqiGw0EYkLoSYQSXQdTqAH1TQAlKsAeSrdBGRfgp3hHJeyGbs1FC3zoG78yGf3+tUzoGYjWaiFaZEhA4GQ6Wy3To8wjHYiEhEynrRXRQUxjwwN1wUwkPWxwRyKtLqjWlAkBEsjsNMOzFCgJPVWduzvAn6mSKHGgrCqKLbjowOoeogwEAMIyH85CAo+iCyDkt4dhAXwMsOQgiJ83w0L8WJgswba5C64AUMCjSEZAvygAAZIxoAAQSwF+mBiJZi6RRMIgrDwCQa4bkCX7EPC1q8UyeBTImFogf6vJAswkGyNBcEIfCkm8bsMlyUCiigX0sYKZCBpGvoZoKXuum7HRvxMkw8SMAQQJSXZoBGUppn8kyboel6PqcQGCkeZ5oAAPxecZLDAeFnmQhOkzTooYk9MBhmxb5CDaQluw6XZ5EuhGLr8YJwnrogYmbBJP6kDkXDrvklCWLVJAUCIrTwZY1XSu6mDIICACM3G1OVQmgGu-R7DhAA8aByKhkKYKwkAAEZiqQSJAkCTDyGkABujC2UUjKIKYUCMO61VAumoD7UdjBjktsiQv1vVkPCdgAKwAAx-YV5ERk17AtX+CoOI+g2GIe4oOE4sOlBY1juUUETPL1vLAJ1qU9YNEQjAeJjHpAA2blNa2bfA908b+mH7XAXK4bIgyZJQXWKPjfVk71xW7Ds5h-IdsiSKwfz9H8E0kJtzyPvIoCsqAAAGFAehQ4CSCZyspu1oCvgEUnSw9jBNC8zKvfVXDkVwOxzetrCICkmC22At6SAo8gAHLSow-woK8fim0yxN4AAQo7zvqjsLrELBbh4FY-t3deyU7mlkNMNDiBI3gQKZyaRKIAAaqL4vadtuSu6MiiNIrijUP0CtKxQaTSABio8mF1foPAghrUXoCwNROZ5qAES52MFTtXNq0bbydhz9TdgoNtERYVNsDIJ74CCJgsjrX0iuwPrQy+1qQ8j7mfwTzgl4REy1dFIReZINg4+j4w691-R8jyAqggIAkE-uPSeKNp6nlnlTBelN57gVXkideDtkBMAAI6sHALEIBitr6gLvu1B+RRTDOAAEwAGYAAsP1cgx12D9MhoAKSeXtpHYgT86EUMYRFIoeAPZ-x9o+f2gc+jyBDiUcOrDMDRzdqAVUP0fpcO4XHBOScUApxVOOScckC7Z1zvnEwWci6lzFideE0jPJMO4VY6xAA9dhRQfoADZFF2RRLQhxAB2Fxnl0A9GKIeexoAfoAA5vG8TmsAZBzskRAA


Solution

  • Try it with

    const errorMiddleware: Middleware<{}, unknown, ThunkDispatch<unknown, unknown, AnyAction>> =
      ({ dispatch }) =>
      (next) =>
      async (action) => {
    

    no need to type things left and right of the = - typing it on one side will carry over to the other side.