createAsyncThunk.withTypes() корисна можливість @reduxjs/toolkit

У цій статті розберемо ще одну маловідому, але не менш корисну можливість@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

toolkit

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

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

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

де:

– stateRootState– Тип вашого кореневого стейту. Значення такого типу повернеgetState

– rejectValueAnyErrorType– Тип значення, яке ви будете використовувати вrejectWithValue

– extraAnyExtraArgumentType– Тип будь-якого екстра аргументу, який ви опціонально використовуватимете у ваших санчатах

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

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

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

const createAppAsyncThunk = createAsyncThunk.withTypes<ThunkApiConfig>()

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

Джерело