При использовании typesafe-actions
мы можем создать действие без использования констант в нашем приложении, например так:
export const toggle = createStandardAction('todos/TOGGLE')<string>();
И затем в редукторе мы сделаем что-то подобное, чтобы сузитьвниз по типу в каждом case
блоке:
import { ActionType, getType } from 'typesafe-actions';
import * as todos from './actions';
type TodosAction = ActionType<typeof todos>;
export default (state: Todo[] = [], action: TodosAction) => {
switch (action.type) {
case getType(todos.add):
// Below action type is narrowed to: { type: "todos/ADD"; payload: Todo; }
return [...state, action.payload];
...
default:
return state;
}
Однако в моем случае я использую async-flow
, поэтому мои действия выглядят так:
import { ActionType, createAsyncAction } from 'typesafe-actions';
import {
getAsyncFetchActionConstants,
getAsyncCreateActionConstants,
getAsyncDeleteActionConstants,
} from '../utils/asyncActions.utils';
const BASE_ACTION = 'AUTH';
export const fetchAuth = createAsyncAction(
...getAsyncFetchActionConstants(BASE_ACTION))<void, AuthState, Error>();
export const createAuth = createAsyncAction(
...getAsyncCreateActionConstants(BASE_ACTION))<void, AuthState, Error>();
export const deleteAuth = createAsyncAction(
...getAsyncDeleteActionConstants(BASE_ACTION))<void, AuthState, Error>();
export type AuthRequestActions
= ActionType<typeof fetchAuth.request> | ActionType<typeof createAuth.request> | ActionType<typeof deleteAuth.request>;
export type AuthSuccessActions
= ActionType<typeof fetchAuth.success> | ActionType<typeof createAuth.success> | ActionType<typeof deleteAuth.success>;
export type AuthErrorActions
= ActionType<typeof fetchAuth.failure> | ActionType<typeof createAuth.failure> | ActionType<typeof deleteAuth.failure>;
export type AuthActions = AuthRequestActions | AuthSuccessActions | AuthErrorActions;
getAsync[Fetch|Create|Delete]ActionConstants
- это просто вспомогательные функции, которые возвращают массив из 3 строк:
export function getAsyncActionConstants(actionName, entityName): [string, string, string] {
return [
`${ actionName }_${ entityName }_${ ASYNC_REQUEST }`,
`${ actionName }_${ entityName }_${ ASYNC_SUCCESS }`,
`${ actionName }_${ entityName }_${ ASYNC_FAILURE }`,
];
}
И в моем редукторе у меня есть:
import { getType } from 'typesafe-actions';
import { AUTH_INITIAL_STATE } from './auth.constants';
import { fetchAuth, createAuth, deleteAuth, AuthActions, AuthActions } from './auth.actions';
export function authReducer(state: AuthState = AUTH_INITIAL_STATE, action: AuthActions) {
switch (action.type) {
case getType(fetchAuth.success):
// TS ERROR: Property 'payload' does not exist on type 'AuthActions'. Property 'payload' does not exist on type 'EmptyAction<string>'.
return action.payload;
...
default:
return state;
}
}
Я бы хотелчтобы можно было работать как в первом (не асинхронном) примере без приведения.
Кроме того, было бы замечательно, если бы кто-то мог предложить, как создать type AuthActions
без такого большого количества шаблонов.