我正在尝试将Redux状态存储与TypeScript结合使用。我正在尝试使用Redux的官方类型,并希望对connect
方法(将mapStatetoProps
和mapDispatchToProps
与组件连接起来)进行类型安全的整个调用。
我通常看到的方法mapStatetoProps
和mapDispatchToProps
只是自定义类型的,并返回组件props的一部分,如下所示:
function mapStateToProps(state: IStateStore, ownProps: Partial<IComponentProps>)
: Partial<IProjectEditorProps> {}
function mapDispatchToProps (dispatch: Dispatch, ownProps: Partial<IComponentProps>)
: Partial<IProjectEditorProps> {}
这是类型化的,可以工作,但并不真正安全,因为它可能会示例化一个缺少属性的组件,因为Partial接口的使用允许不完整的定义。但是,Partial接口在这里是必需的,因为您可能希望在mapStateToProps
和mapDispatchToProps
中定义一些props,而不是在一个函数中定义所有props。这就是为什么我想避免这种风格。
我目前尝试使用的是直接将函数嵌入到connect
调用中,并使用redux提供的泛型类型输入connect调用:
connect<IComponentProps, any, any, IStateStore>(
(state, ownProps) => ({
/* some props supplied by redux state */
}),
dispatch => ({
/* some more props supplied by dispatch calls */
})
)(Component);
然而,这也抛出了错误,嵌入式mapStatetoProps
和mapDispatchToProps
调用不定义 all Props each,因为两者都只需要它们的子集,而是一起定义所有Props。
我如何正确地键入connect调用,以便mapStatetoProps
和mapDispatchToProps
调用是真正类型安全的,并且键入检查两个方法定义的组合值是否提供了所有必需的props,而无需一次定义所有props所需的方法之一?我的方法有可能吗?
3条答案
按热度按时间6vl6ewon1#
选项一:拆分
IComponentProps
最简单的方法可能就是为“state derived props”、“own props”和“dispatch props”定义单独的接口,然后使用交集类型将它们连接到
IComponentProps
中。我们可以这样设置connect函数的泛型参数:
<TStateProps, TDispatchProps, TOwnProps, State>
选项二:让你的函数定义你的Props接口
另一个我见过的方法是利用
ReturnType
mapped type来允许mapX2Props
函数实际定义它们对IComponentProps
的贡献。这里最大的优点是,它减少了一点锅炉板,使它只有一个地方更新时,你添加一个新的Map prop 。
我总是避开
ReturnType
,simplify,因为让你的实现定义你的编程接口“契约”(IMO)感觉很倒退。以一种您不希望的方式更改您的IComponentProps
变得几乎太容易了。但是,由于这里的所有内容都是自包含的,因此它可能是一个可接受的用例。
ebdffaop2#
一种解决方案是将组件属性拆分为state-、dispatch-和own-属性:
eaf3rand3#
非常喜欢@NSjonas的拆分方法,但我也想从他的第二种方法中借鉴一些东西,以便在实用性之间取得平衡,不要让实现完全定义接口,也不要在输入分派操作时过于冗长;