如何为带defaultProps的React Redux组件声明Flow类型?
解决Flow中React组件显式导出时的类型检查问题
我明白你遇到的问题了——当组件带有defaultProps,同时用connect连接Redux时,类型推断模式下一切正常,但显式声明导出类型就会触发Flow报错,哪怕用精确类型{|...|}也一样。这其实是因为Flow对组件内部接收的Props和外部传入的Props有严格的区分,而显式声明时我们没对齐这种差异。
问题根源
你的组件类声明的Props里prop2是必填的,但defaultProps又把它设为可选值。在类型推断时,Flow会自动帮你处理这个矛盾:它知道外部传入时prop2可以省略,内部会被defaultProps填充。但当你显式导出时,必须手动明确这种“外部可选、内部必填”的类型关系,否则Flow会严格校验,认为你传递的Props缺少必填字段。
具体解决方案
方案1:拆分Props类型(最通用)
把Props拆成外部传入的OwnProps和组件内部实际接收的Props,让Flow清晰区分两者:
// @flow import * as React from 'react' import { connect } from 'react-redux' // 外部传入的Props:prop2可选,因为有default兜底 type OwnProps = {| prop1: number, prop2?: number |} // 组件内部接收的Props:所有字段必填,defaultProps会补全prop2 type ComponentProps = {| prop1: number, prop2: number |} class ExampleClass extends React.Component<ComponentProps> { static defaultProps: $Shape<OwnProps> = { prop2: 1 } render() { return this.props.prop1 + this.props.prop2 } } // 假设你的mapStateToProps是这样的 const mapStateToProps = (state: any) => ({ prop1: state.someReducer.prop1, }) // 显式给connect指定类型参数,对齐OwnProps和ComponentProps export default connect<ComponentProps, {}, OwnProps, any>(mapStateToProps)(ExampleClass)
方案2:使用React.AbstractComponent(Flow 0.100+推荐)
Flow的React.AbstractComponent会自动处理defaultProps的类型映射,不用手动拆分类型:
// @flow import * as React from 'react' import { connect } from 'react-redux' type ComponentProps = {| prop1: number, prop2: number |} class ExampleClass extends React.Component<ComponentProps> { static defaultProps = { prop2: 1 } render() { return this.props.prop1 + this.props.prop2 } } const mapStateToProps = (state: any) => ({ prop1: state.someReducer.prop1, }) // 声明导出组件的类型为AbstractComponent,外部Props允许prop2可选 const ConnectedExample: React.AbstractComponent<{| prop1: number, prop2?: number |}, ComponentProps> = connect(mapStateToProps)(ExampleClass) export default ConnectedExample
关键注意点
- 不管用普通对象类型还是精确类型
{|...|},处理逻辑完全一致,只需要把类型改成精确格式即可。 connect的类型参数顺序是:connect<PropsFromState, PropsFromDispatch, OwnProps, State>,所以要对应填对位置。
内容的提问来源于stack exchange,提问作者Jacob Wallström
相关产品推荐
相关产品推荐

