interface IOwnProps {
startDate: number
endDate: number
}
interface IOwnState {
current: number
}
const mapStateToProps = (state, ownProps: IOwnProps) => ({
opEntitiesTable: getOpEntitiesTableData(state),
...ownProps,
})
const mapDispatchToProps = dispatch => ({
fetchOpEntities: bindActionCreators(fetchOpEntities, dispatch),
})
const mapState = getReturnOfExpression(mapStateToProps)
const mapDispatch = getReturnOfExpression(mapDispatchToProps)
type IMapStateToProps = typeof mapState
type IMapDispatchToProps = typeof mapDispatch
type IProps = IMapStateToProps & IMapDispatchToProps
class LogTable extends React.Component<IProps, IOwnState> {
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(LogTable)
使用该组件时, Props 类型应该按照 IOwnProps 来匹配而不是 IProps(包含了从 redux map 过来的)。因此,会提示 opEntitiesTable 需传。
应该按照 IOwnProps 来检查 props,所以使用该组件只需要传 startDate 和 endDate 即可。
如果使用 react-redux 的 connect,该 connect 的 types 定义支持泛型,这样使用就正常了:
export default connect<IMapStateToProps, IMapDispatchToProps, IOwnProps>(
mapStateToProps,
mapDispatchToProps
)(LogTable)
使用该组件,会按照 IOwnProps 来检查 props。
dva 的 connect 的类型定义没有泛型支持。
1.2.1 版本
我尝试修改 connect 的 type definition,可以看下这个:
https://github.com/dvajs/dva/compare/master...ruiming:patch-1
但是这样做会有新的问题,connect 无法使用装饰器语法 @connect,总是会提示不匹配,这个问题似乎还无解(https://github.com/DefinitelyTyped/DefinitelyTyped/issues/19020)。
但不适用装饰器语法的话,像下面这样写的,是可以正常工作的并正确检查 Props(只检查 IOwnProps):
export default connect<IMapStateToProps, IMapDispatchToProps, IOwnProps>(
mapStateToProps,
mapDispatchToProps
)(LogTable)
@yvanwangl 嗯,我之前用 Antd 的 @Form.create() 也是不能用,最后也是像你这样做解决的。
你说的第二点,这样做会丢失使用该组件时的 OwnProps 属性的静态检查吧?你可以参考我最上面"实际效果"的代码,通过 connect 的泛型支持是可以处理这个问题的。
@ruiming 嗯,我之前试过那么写,但是感觉如果很多组件都这么写有些许麻烦(懒)
@yvanwangl 但这样你这个组件对使用者而言,用没用 TypeScript 都一样了,没有了补全和静态检查。我不是很认可这种写法。不过确实麻烦了点,获取 mapStateToProps 的返回值类型还要通过污染运行时来实现。
@ruiming 是的 👍
@yvanwangl 但这样你这个组件对使用者而言,用没用 TypeScript 都一样了,没有了补全和静态检查。我不是很认可这种写法。不过确实麻烦了点,获取 mapStateToProps 的返回值类型还要通过污染运行时来实现。
是不是用 dva 和 ts 后。所有组件的 Props 都需要设置为any?请问这个问题解决了吗。
同求类似 redux 的泛型支持,现在 stateProps 和 dispatchProps 都会污染真实组件参数,很影响封装组件的体验
@ouabing 可以先试着直接用 Redux 的 connect 而不是 dva 的。另外 TS 已经有了 returnType 运算符了,我前面的 demo 太啰嗦了。
@ruiming 我试试
所以dva的connect会支持泛型吗?或者我直接用react-redux的connect?
import { ComponentClass } from 'react'
import {
connect as nativeConnect,
MapDispatchToPropsParam,
MapStateToPropsParam
} from 'react-redux'
export type ComponentDecorator<P = any> = <T extends ComponentClass<P>>(WrappedComponent: T) => T
export const connect: <P, S>(
mapState: MapStateToPropsParam<Partial<P>, P, S>,
mapDispatch?: MapDispatchToPropsParam<Partial<P>, P>
) => ComponentDecorator = nativeConnect as any
The same question.
是否有最优解
Most helpful comment
@ruiming 其实这个问题是 Ts 的,我自己项目没有使用dva也有这个问题,可以通过一个 hack 手段解决;
1、对于connect使用装饰器可以这么用 @(connect(mapStateToProps, mapDispatchToProps) as any)
2、对于提示 redux 注入属性需传递的问题,可以这么解决 export default LogTable as any;
可以参考我的项目代码1、项目代码2