【问题标题】:How do I properly set types for higher-order class components in TypeScript?如何在 TypeScript 中正确设置高阶类组件的类型?
【发布时间】:2018-02-20 00:33:12
【问题描述】:

我有一个实用函数,它接受一个(现在未使用的)选项参数并返回一个高阶组件包装函数。

如何在组件上正确设置类型,以让包装组件的用户看到底层包装组件的类型以及来自withAppContext 高阶组件的附加上下文类型?

type AppContext = {
  id: string;
};

const withAppContext = (opts) => {
  const hoc = WrappedComponent => {
    class WithAppContext extends React.Component<any, any> {
      static contextTypes = {
        appContext: PropTypes.shape({
          id: PropTypes.string,
        }),
      };

      context: AppContext;

      render() {
        return React.createElement(WrappedComponent, {
          ...this.props,
          ...this.context
        });
      }
    }
    return WithAppContext;
  };
  return hoc;
};

当仅扩展 React.Component(没有 &lt;any, any&gt;)时,我收到关于 IntrinsicAttributes 不包含我正在传递的道具的投诉(即,我似乎无法将道具传递给包装的组件):

error TS2339: Property 'onClick' does not exist on type
    'IntrinsicAttributes
    & IntrinsicClassAttributes<WithCustomerContext>
    & Readonly<{ children?: React...'.

【问题讨论】:

    标签: reactjs typescript


    【解决方案1】:

    您的hoc 函数应该是通用的,以便可以根据使用情况推断属性:

    const withAppContext = function (opts) {
    
        function hoc <P>(WrappedComponent: React.StatelessComponent<P>) : React.ComponentClass<P>
        function hoc <P, T extends React.Component<P, React.ComponentState>, C extends React.ComponentClass<P>>(WrappedComponent: React.ClassType<P, T, C>) : React.ComponentClass<P>
        function hoc <P>(WrappedComponent: any ) : React.ComponentClass<P>
        {
            class WithAppContext extends React.Component<P> {
    
                context: AppContext;
    
                render() {
                    return React.createElement(WrappedComponent, Object.assign({}, this.props, this.context));
                }
            }
            return WithAppContext;
        };
        return hoc;
    }
    
    class MyComponent extends React.Component<{ prop: string }>{
    
    }
    const MyComponentWithContext = withAppContext({})(MyComponent);
    let d = <MyComponentWithContext prop =""  />
    
    
    
    let GreeterComponent = function (props: {name: string, greeting: string}){
        return <div>{props.greeting} {props.name}!</div> 
    }
    const GreeterComponentContext = withAppContext({})(GreeterComponent);
    let d2 = <GreeterComponentContext  name="" greeting=""  />
    

    【讨论】:

      猜你喜欢
      • 2019-07-25
      • 1970-01-01
      • 2021-11-23
      • 2023-03-26
      • 2012-10-25
      • 2020-05-17
      • 1970-01-01
      相关资源
      最近更新 更多