MapDispatchToProps 导致父组件中的 Typescript 错误,期望 Actions 作为 props 传递

Posted

技术标签:

【中文标题】MapDispatchToProps 导致父组件中的 Typescript 错误,期望 Actions 作为 props 传递【英文标题】:MapDispatchToProps causes Typescript Error in parent-component, expecting Actions to be passed as props 【发布时间】:2019-05-28 10:09:54 【问题描述】:

在我的子组件中,我正在定义 MapDispatchToProps,将它们传递给 connect 并相应地定义一个在 React.Component Props 接口中扩展的接口 PropsFromDispatch。现在在我的父组件中,Typescript 告诉我它缺少我在 PropsFromDispatch 中定义的属性。

这似乎并不完全荒谬,因为我将它们定义为 React.Component Props 接口的一部分,但是我希望“连接”能够像处理我的 PropsFromState 一样处理这个问题,我也不必从父组件传递到子组件,而是从状态映射到道具。

/JokeModal.tsx

...

interface Props extends PropsFromState, PropsFromDispatch 
    isOpen: boolean
    renderButton: boolean


...

const mapDispatchToProps = (dispatch: Dispatch<any>): 
PropsFromDispatch => 
    return 
        tellJoke: (newJoke: INewJoke) => dispatch(tellJoke(newJoke)),
        clearErrors: () => dispatch(clearErrors())
    


interface PropsFromDispatch 
    tellJoke: (newJoke: INewJoke) => void
    clearErrors: () => void


...

export default connect(mapStateToProps, mapDispatchToProps)(JokeModal);

/Parent.tsx

...

button = <JokeModal isOpen=false renderButton=true /> 
...

在 /Parent.tsx 的这一行中,Typescript 现在告诉我:

Type ' isOpen: false; renderButton: true; ' is missing the 
following properties from type 'Readonly<Pick<Props, "isOpen" | 
"renderButton" | "tellJoke" | "clearErrors">>': tellJoke, clearErrors 
ts(2739)

有趣的是,我可以通过删除 MapDispatchToProps 并直接将操作传递给连接来完全避免该错误(包括已经在操作创建器中调度):

export default connect(mapStateToProps,  tellJoke, clearErrors )(JokeModal);

不过我想知道如何在这里使用 MapDispatchToProps 以及为什么 Typescript 期望我将这些操作传递给子组件?

很高兴听到您的建议!

【问题讨论】:

react 和 @types/react 使用的是什么版本? @CoderSpinoza "react": "^16.6.3" 并使用 create-react-app 中的 "react-scripts-ts": "^4.0.8" 和 "typescript": "^3.2 .1" 您确定不先导出再导入未连接的 JokeModal 组件吗? 我正在导入类而不是连接的组件并遇到此问题。谢谢@Yakimych 【参考方案1】:

我能够重现您的问题,问题显然出在source code 中mapDispatchToProps 函数的类型签名中,您可以看到它有一个类型参数Action = AnyAction

export interface Dispatch<A extends Action = AnyAction> 
  <T extends A>(action: T): T

解决你的问题的方法是将Dispatch&lt;any&gt;改为Dispatch&lt;AnyAction&gt;

const mapDispatchToProps = (dispatch: Dispatch<AnyAction>): PropsFromDispatch

请注意,由于您使用的是 redux-thunk,因此类型系统可能不允许您在 thunk 上调用 dispatch,因此您可能不得不通过调用来作弊

clearErrors: () => dispatch<any>(clearErrors());

或使用ThunkDispatchThunkAction 进行相当冗长的输入。我在这里有一个这样的输入示例:ThunkDispatch 和相应的ThunkAction。请注意,我使用typesafe-actions。

【讨论】:

以上是关于MapDispatchToProps 导致父组件中的 Typescript 错误,期望 Actions 作为 props 传递的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jest 时是不是有另一种方法来模拟组件的 mapDispatchToProps

mapStateToProps 与 mapDispatchToProps [重复]

使用单个 mapDispatchToProps 的缺点是啥?

如何访问 mapDispatchToProps 中 mapStateToProps 添加的属性?

React-redux mapStateToProps,mapDispatchToProps 如何使用

redux mapDispatchToProps 不更新状态