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

时间:2019-01-01 10:54:18

标签: reactjs typescript redux react-redux redux-thunk

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

这似乎并不完全荒谬,因为我将它们定义为React.Component Props接口的一部分,但是我希望'connect'能够像处理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的这一行中,打字稿现在告诉我:

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

有趣的是,我可以通过删除MapDispatchToProps并直接将动作直接传递给connect(包括动作创建者中已分派的动作)来完全避免错误:

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

尽管如此,我还是想知道如何在这里使用MapDispatchToProps以及为什么Typescript希望我将这些操作传递给子组件?

很高兴听到您的建议!

1 个答案:

答案 0 :(得分:5)

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

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

您的问题的解决方案是将Dispatch<any>更改为Dispatch<AnyAction>

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

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

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

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