Чтобы сделать ваш код компилируемым, я сделал следующие предположения
import { ThunkAction, ThunkDispatch } from 'redux-thunk';
const FETCH = 'fetch';
interface FetchAction {
[FETCH]: object;
}
interface FetchResponseAction {
prop2: string;
}
const APP_LIST = 'APP_LIST';
const APP_LIST_SUCCESS = 'APP_LIST_SUCCESS';
interface ListModel {
prop3: string;
}
А после вашего кода
type ThunkResult<R> = ThunkAction<R, State, undefined, AppActions>;
type ThunkDispatcher = ThunkDispatch<State, undefined, AppActions>;
С учетом приведенных выше предположений ваш код становится компилируемым со следующей модификацией
export const loadList = (): ThunkResult<AppActions> => (dispatch: ThunkDispatcher) => dispatch(loadListCreator());
ThunkResult<AppActions>
должен иметь тип для R = AppActions
. R
- это возвращаемое значение из функции типа ThunkResult
. В Redux-Thunk исходный код ThunkAction
определяется следующим образом
export type ThunkAction<
TReturnType,
TState,
TExtraThunkArg,
TBasicAction extends Action
> = (
dispatch: ThunkDispatch<TState, TExtraThunkArg, TBasicAction>,
getState: () => TState,
extraArgument: TExtraThunkArg
) => TReturnType;
То есть ThunkAction
(на котором основан ThunkResult
) - это функция, которая возвращает значение типа TReturnType
.
Затем вы пытаетесь сделать loadlist
типа ThunkResult<>
равным (dispatch: ThunkDispatcher) => dispatch(loadListCreator())
. По сути это также функция, но возвращающая результат вызова dispatch
. dispatch
имеет тип ThunkDispatcher
и из источника , имеет тип
export interface ThunkDispatch<
TState,
TExtraThunkArg,
TBasicAction extends Action
> {
<TReturnType>(
thunkAction: ThunkAction<TReturnType, TState, TExtraThunkArg, TBasicAction>
): TReturnType;
<A extends TBasicAction>(action: A): A;
}
Таким образом, перегруженная функция принимает функцию с одним пакетом типа A
и возвращает результат типа A
. Поскольку dispatch
вызывается с результатом вызова loadListCreator()
, который возвращает результат типа AppActions
, A
выводится как AppActions
.
Исходный код правильно не скомпилирован, так как вы хотите назначить функцию, возвращающую AppActions
, функции, возвращающей AppResponseActions
. AppActions
является типом объединения и может быть либо AppResponseActions
, либо AppListAction
. Если это AppListAction
, его нельзя присвоить AppResponseActions
.
Кажется, я четко описал: -)
С практической точки зрения ваш код немного усложнен.
Подумайте об упрощении этого пути.
Унаследовать все действия от Тип действия
import { Action } from 'redux';
interface AppListAction extends Action {
type: typeof APP_LIST,
[FETCH]: {},
}
Установить тип ThunkResult
на следующий
type ThunkResult = ThunkAction<void, State, undefined, AppActions>;
Скорее всего, вам не нужно TReturnType
. Thunk-действия просто отправляют все необходимое внутри кода и ничего не возвращают (void
).
Создатели действий для синхронизации действий могут выглядеть как
interface SyncAction1 extends Action {
type: 'SYNC_ACTION',
argument: string
}
const SomeSyncAction = (argument: string) => <SyncAction1>{ type: 'SYNC_ACTION', argument }
Создатели действий для асинхронных действий могут выглядеть как
export const loadList = (): ThunkResult => (dispatch: ThunkDispatcher) => {
dispatch(/* start loading */);
const result = await // load api call
dispatch(loadListCreator(result));
}
Редуктор будет выглядеть
export function loadReducer (state = initalState, action: AppActions)
// reducer code