【问题标题】:How do I define component type?如何定义组件类型?
【发布时间】:2020-01-26 13:46:00
【问题描述】:

我正在尝试编写一个将Higher Order Components 作为参数并返回与redux 存储连接的组件的函数。但是这段代码在最后一行有一个类型错误。如何正确定义类型?

import React from 'react'
import { connect } from 'react-redux'
import { Dispatch } from 'redux'
import { AppState } from '~/store'
import { decrement, increment } from '~/store/home'

export type CountableProps = StateType & DispatchType

type StateType = ReturnType<typeof mapStateToProps>
const mapStateToProps = (state: AppState) => ({
  count: state.home.count
})

type DispatchType = ReturnType<typeof mapDispatchToProps>
const mapDispatchToProps = (dispatch: Dispatch) => ({
  increment: () => dispatch(increment()),
  decrement: () => dispatch(decrement())
})

const createCountableComponent =
  <P extends CountableProps>(Component: React.ComponentType<P>) =>
    class extends React.Component<P> {
      componentDidMount() {
        // do something...
      }

      render() {
        return <Component {...this.props} />
      }
    }

export const countable = <P extends CountableProps>(Component: React.ComponentType<P>) =>
  connect(
    mapStateToProps,
    mapDispatchToProps
  )(createCountableComponent(Component))

输入错误

TS2345: Argument of type 'typeof ConfigurableComponent' is not assignable to parameter of type 'ComponentType<Matching<CountableProps, P>>'

【问题讨论】:

    标签: reactjs typescript redux higher-order-components


    【解决方案1】:

    显式键入连接函数似乎有效:

    export const countable = <P extends CountableProps>(Component: React.ComponentType<P>) =>
        connect<StateType, DispatchType, Omit<P, keyof (StateType & DispatchType)>>(
            mapStateToProps,
            mapDispatchToProps
        )(createCountableComponent(Component) as any);
    

    我们可以将 createCountableComponent(Component) 转换为 any,因为我们使用正确的类型(state、dispatch 和 ownProps 类型)键入了 connect。这意味着当您使用此组件时,您只会看到不可计数的道具(这是所需的解决方案)。

    所以:

    class Test extends React.Component<{test: string}> {
        render() {
            return <div />;
        }
    };
    
    countable(Test)
    

    会报错,而:

    class Test extends React.Component<CountableProps & {test: string}> {
        render() {
            return <div />;
        }
    };
    
    const Test2 = countable(Test)
    <Test2 /> -> intelisense will only give you test now :)
    

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回答。我试过了,但得到了另一个类型错误。 TS2345: Argument of type 'ComponentType&lt;P&gt;' is not assignable to parameter of type 'ComponentType&lt;CountableProps&gt;'.
    猜你喜欢
    • 1970-01-01
    • 2020-03-10
    • 2019-11-23
    • 2022-12-11
    • 2019-10-02
    • 1970-01-01
    • 2012-08-11
    • 2011-01-18
    • 2018-11-16
    相关资源
    最近更新 更多