В этой статье разберем еще одну малоизвестную, но не менее полезную возможность @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
может быть совсем не просто