调度 thunk 动作创建者在 TypeScript 中不匹配

Posted

技术标签:

【中文标题】调度 thunk 动作创建者在 TypeScript 中不匹配【英文标题】:Dispatching thunk action creator does not match in TypeScript 【发布时间】:2019-08-14 16:41:41 【问题描述】:

我正在尝试使用redux-thunk 创建一个异步操作。它几乎可以工作,但唯一的问题是dispatch(f()) 导致 TSC 出错。

读取redux official document,它接受函数。

代码在这里:

import  applyMiddleware, createStore, Reducer  from 'redux';
import thunkMiddleware,  ThunkAction  from 'redux-thunk';

// --------------------------------
// State

export interface IAppState 
  active: boolean;

const initialAppState: IAppState = 
  active: false,
;

// --------------------------------
// Actions and action creators

type AppAction =  type: 'turnOn'  |  type: 'turnOff' ;

function turnOn (): AppAction 
  return  type: 'turnOn' ;


function turnOff (): AppAction 
  return  type: 'turnOff' ;


// --------------------------------
// Reducers

const rootReducer: Reducer<IAppState, AppAction> = (
  state = initialAppState,
  action,
) => 
  switch (action.type) 
    case 'turnOn': return  ...state, active: true ;
    case 'turnOff': return  ...state, active: false ;
    default: return state;
  
;

// --------------------------------
// Store

export function createAppStore () 
  return createStore<IAppState, AppAction, , >(
    rootReducer,
    applyMiddleware(thunkMiddleware),
  );


const store = createAppStore();

// --------------------------------
// Use store

store.dispatch(turnOn());
store.dispatch(turnOff());

// --------------------------------
// Thunk action

function turnOnAndOff (
  delay: number,
): ThunkAction<Promise<void>, IAppState, null, AppAction> 
  return (dispatch) => new Promise((resolve) => 
    dispatch(turnOn());
    setTimeout(() => 
      dispatch(turnOff());
      resolve();
    , delay);
  );


store.dispatch(turnOnAndOff(1000)); // ERROR

在最后一行,TSC 说它们的类型不匹配。

TypeScript 错误:“ThunkAction、IAppState、null、AppAction>”类型的参数不可分配给“AppAction”类型的参数。 类型 'ThunkAction, IAppState, null, AppAction>' 中缺少属性 'type' 但类型 ' type: "turnOff"; '。 TS2345

如果我改为写turnOnAndOff(1000) as any,它可以正常工作。

如何让dispatch()接受函数?

【问题讨论】:

【参考方案1】:

当前的 redux-thunk 类型不支持使用 store.dispatch 调度 thunk 操作。通常您会有一个 mapDispatchToProps,您可以在其中将调度键入为 ThunkDispatch。您可以进行内联转换,即使它很丑陋并且转换失去了类型安全性。看到这个答案:How to dispatch an Action or a ThunkAction (in TypeScript, with redux-thunk)?

【讨论】:

好的,我知道现在不可能。对象样式mapDispatchToPropsconnect() 就可以了。谢谢! 我刚开始学习 Typescript,这对我来说确实是一个重大的退步。这让我很难过。

以上是关于调度 thunk 动作创建者在 TypeScript 中不匹配的主要内容,如果未能解决你的问题,请参考以下文章

jest redux-thunk 测试是不是调度了相同模块的操作

React-Redux-Thunk:动作不返回调度

Redux thunk:从分派的动作返回承诺

Redux thunk:如何等待异步操作的完成

Redux thunk - 嵌套调度的函数/动作

Redux-Thunk - 异步动作创建者承诺和链接不起作用