typescript - איך להכין עטיפה מותאמת אישית ל-createAsyncThunk


יש לי את העטיפת thunk הזו שבה השתמשתי בתחילה באפליקציית JS.

לכן, אני מתקשה להבין איך להקליד את זה, בעיקר בגלל סוגי ה-thunk וה-thunkApi:

export const asyncThunkHandleError = (
  typePrefix: string,
  thunk: any, // how to type this one and thunkAPI?
  errorMessage?: string
) =>
  createAsyncThunk(typePrefix, async (arg: any, thunkAPI: any) => {
    try {
      // actually call the thunk
      return await thunk(arg, thunkAPI);
    } catch (error: any) {
      // here we will dispatch the modal with the error message
      thunkAPI.dispatch(
        openModal({
          title: `Error in ${typePrefix}`,
          children: `${error instanceof Error ? error.message : 'Unknown error'}`,
        })
      );
      throw thunkAPI.rejectWithValue(error.response?.data || errorMessage);
    }
  });

זה נשלח כך:

// SomeComponent.tsx
dispatch(getPokemons());

הצליל עטוף כך:

// actions/pokemons.ts
const getPokemons = asyncThunkHandleError(
  'pokemons/getPokemons',
  async (arg: any, thunkAPI: any) => {
    const someNetworkCall = await fetch('https://example.com');

    return someNetworkCall.json();
  },
  'An error occurred'
);

בדקתי בקבצי התלות ומצאתי משהו כמו סוגים BaseThunkAPI, GetThunkAPI, AsyncThunkPayloadCreator וכדומה בנתיב .../@reduxjs/toolkit/src/createAsyncThunk.ts אבל אני לא בטוח איך ליישם את זה או אם זה בכלל נכון.

תשובה #1

ובכן, מצאתי פתרון למקרה דומה כאן, יש לו אפילו מגרש משחקים:

import {createAsyncThunk,AsyncThunkPayloadCreator,AsyncThunk} from '@reduxjs/toolkit'

interface ThunkAPIConfig {}

export const createMyOwnAsyncThunk = <Returned, ThunkArg = any>(
  type: string,
  thunk: AsyncThunkPayloadCreator<Returned, ThunkArg>,    // <-- very unsure of this - have tried many things here
): AsyncThunk<Returned, ThunkArg, ThunkAPIConfig> => {
  return createAsyncThunk<Returned, ThunkArg, ThunkAPIConfig>(
    type,
    async (arg, thunkAPI) => {
      try {
        // do some stuff here that happens on every action
        return await thunk(arg, thunkAPI)
      } catch (err) {
        // do some stuff here that happens on every error
        return thunkAPI.rejectWithValue(null)
      }
    },
  )
}