MapDispatchToProps 导致父组件中的 Typescript 错误,期望操作作为道具传递 [英] MapDispatchToProps causes Typescript Error in parent-component, expecting Actions to be passed as props
问题描述
在我的子组件中,我定义了 MapDispatchToProps,将它们传递给 connect 并相应地定义了一个接口 PropsFromDispatch,该接口在 React.Component Props 接口中扩展.现在在我的父组件中,Typescript 告诉我它缺少我在 PropsFromDispatch 中定义的属性.
In my child component I am defining MapDispatchToProps, pass them into connect and accordingly define an interface PropsFromDispatch that is extended in React.Component Props Interface. Now in my parent component Typescript is telling me that it is missing the properties that I defined in PropsFromDispatch.
这似乎并不完全荒谬,因为我将它们定义为 React.Component Props 接口的一部分,但是我希望connect"能够像处理我的 PropsFromState 一样处理这个问题,我也不必从父组件传递到子组件,而是从状态映射到道具.
This doesn't seem entirely absurd, as I am defining them as part of the React.Component Props interface, however I would expect 'connect' to take care of this the same way that it is taking care of my PropsFromState, which I also don't have to pass from parent to child component, but is mapped from the State to Props.
/JokeModal.tsx
/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
/Parent.tsx
...
button = <JokeModal isOpen={false} renderButton={true} />
...
在/Parent.tsx 的这一行中,Typescript 现在告诉我:
In this line of /Parent.tsx Typescript is now telling me:
Type '{ isOpen: false; renderButton: true; }' is missing the
following properties from type 'Readonly<Pick<Props, "isOpen" |
"renderButton" | "tellJoke" | "clearErrors">>': tellJoke, clearErrors
ts(2739)
有趣的是,我可以通过删除 MapDispatchToProps 来完全避免错误,而是将动作直接传递到连接中(包括动作创建者中已经存在的调度):
Interestingly I can avoid the error entirely by removing MapDispatchToProps and instead passing in the actions directly into connect(including dispatch already in the action creator):
export default connect(mapStateToProps, { tellJoke, clearErrors })(JokeModal);
不过我想知道如何在这里使用 MapDispatchToProps 以及为什么 Typescript 期望我将这些操作传递给子组件?
Nevertheless I would like to know how to use MapDispatchToProps here and also why Typescript is expecting me to pass these actions to the child component?
很高兴听到您的建议!
推荐答案
我能够重现您的问题,问题显然出在 mapDispatchToProps 函数的类型签名中"https://github.com/reduxjs/redux/blob/32ac7e64bf548e0287807fae9e622aa9c55ff065/index.d.ts#L121" rel="noreferrer">源码,可以看到它有一个类型参数Action = AnyAction
I was able to reproduce your problem and the issue is apparently in the type signature of the mapDispatchToProps
function in the source code, you can see that it has a type parameter Action = AnyAction
export interface Dispatch<A extends Action = AnyAction> {
<T extends A>(action: T): T
}
解决你的问题的方法是将Dispatch
改为Dispatch
:
The solution to your problem is to change Dispatch<any>
to Dispatch<AnyAction>
:
const mapDispatchToProps = (dispatch: Dispatch<AnyAction>): PropsFromDispatch
请注意,由于您使用的是 redux-thunk,类型系统可能不允许您在 thunk 上调用 dispatch
,因此您可能不得不通过调用来欺骗
Note that since you're using redux-thunk, the type system might not allow you to call dispatch
on a thunk, so you might have to either cheat by calling
clearErrors: () => dispatch<any>(clearErrors());
或者使用 ThunkDispatch
和 ThunkAction
使用相当冗长的输入.我在这里有一个这样打字的例子:ThunkDispatch 和相应的 ThunkAction.请注意,我使用 typesafe-actions.
or use rather verbose typing with ThunkDispatch
and ThunkAction
. I have an example of such a typing here: ThunkDispatch and the corresponding ThunkAction. Note that I use typesafe-actions.
这篇关于MapDispatchToProps 导致父组件中的 Typescript 错误,期望操作作为道具传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!