В этой статье разберем еще одну малоизвестную, но не менее полезную возможность @reduxjs/toolkit

Предыдущая статья по redux и @reduxjs/toolkit

Для начала разберем варианты и возможности типизации createAsyncThunk

Санки можно типизировать как при помощи дженериков,

createAsyncThunk<Returned, ThunkArg, ThunkApiConfig>()

так и при помощи непосредственно аргументов

createAsyncThunk(
  'asyncThunkTypePrefix',
  (arg: ThunkArg, apiConfig: ThunkApiConfig) => {}
)

где:

- Returned – тип возвращаемого санком значения

- ThunkArg – тип аргумента санка

- ThunkApiConfig – тип конфига, его разберем ниже

Я предпочитаю и советую использовать второй метод, поскольку нет необходимости вручную описывать тип возвращаемого значения, особенно, когда ваш санк может вернуть несколько видов ошибок помимо данных. Гораздо проще предоставить это Typescript'у, он прекрасно анализирует все выхода из санка и показывает, например, что вернуться может Data | Error | AxiosError, и вы не будете утопать в огромных сообщениях об ошибках типизации из-за того, что типизация в дженериках отличается от той, что видит Typescript

Теперь посмотрим подробнее ThunkApiConfig:

Обратимся к документации thunkApi в @reduxjs/toolkit

Здесь описаны все возможные поля и пояснения к ним. Однако на практике в основном используется лишь половина из них:

type Store = typeof store
type RootState = ReturnType<Store['getState']>
type AppDispatch = Store['dispatch']

type ThunkApiConfig = {
  state: RootState
  dispatch: AppDispatch
  rejectValue: AnyErrorType
  extra: AnyExtraArgumentType
}

где:

- state: RootState – Тип вашего корневого стейта. Значение такого типа вернет getState

- rejectValue: AnyErrorType – Тип значения, которое вы будете использовать в rejectWithValue

- extra: AnyExtraArgumentType – Тип любого экстра аргумента, который вы опционально будете использовать в ваших санках

Поскольку никому не хочется каждый раз описывать этот тип для каждого нового санка, часто используются функции-обертки помогающие лишь один раз описать тип ThunkApiConfig

export const createAppnAsyncThunk = <Returned, ThunkArg>(
  type: string,
  thunkPayloadCreator: AsyncThunkPayloadCreator<Returned, ThunkArg>,
): AsyncThunk<Returned, ThunkArg, ThunkApiConfig> =>
 createAsyncThunk<Returned, ThunkArg, ThunkApiConfig>(type, thunkPayloadCreator)

A теперь заглянем в глубины документации, куда добираются немногие и посмотрим на способ, который нам предлагает библиотека из коробки - createAsyncThunk.withTypes()

const createAppAsyncThunk = createAsyncThunk.withTypes<ThunkApiConfig>()

Как видим первый метод по сравнению со вторым требует написания большего количество и, что не маловажно, понять и разобраться с типами, предоставляемыми @reduxjs/toolkit для типизации санков, что для новичков в Typescript может быть совсем не просто

Комментарии (0)