首页 > 解决方案 > 为什么类型不能分配给泛型类型

问题描述

我正在尝试构建和键入一个 HOC,它只是将一个组件包装在 ApolloProvider 中。我希望能够将 ref 转发到包装的组件。但是,当我尝试在 forwardRef 组件中传递道具时,我遇到了类型错误

在我的研究狂潮中,我偶然发现了一个关于泛型是问题的答案。

const withProvider = function<P>(WrappedComponent: React.ComponentClass<P>) {

  type Props = P & { forwardedRef?: React.Ref<any> }

  class WithProvider extends React.Component<Props> {
    render() {
      const { forwardedRef, ...props } = this.props
      return (
        <ApolloProvider client={client}>
          <WrappedComponent {...props} ref={forwardedRef} />
        </ApolloProvider>
      )
    }
  }

  hoistNonReactStatics(WithProvider, WrappedComponent)

  return React.forwardRef((props, ref) => (
    <WithProvider {...props} forwardedRef={ref} />
  ))
}

给我错误:


Type '{ forwardedRef: string | ((instance: {} | null) => any) | RefObject<{}> | undefined; children?: ReactNode; }' is not assignable to type 'Readonly<Props>'

对我来说,这些应该匹配,前者应该可以分配给后者。我唯一能想到的是Readonly<Props>包含一个泛型。

有人可以指出我正确的方向吗?

标签: reactjstypescriptgenericstypescript-typingstypescript-generics

解决方案


最后,我找到了解决方案。

您所要做的就是将 props (in React.forwardRef) 的类型作为接收到的类型给出P

  return React.forwardRef((props:P, ref) => (
    <WithProvider {...props} forwardedRef={ref} />
  ));

完整代码:

const withProvider = function<P>(WrappedComponent: React.ComponentClass<P>) {

  type Props = P & { forwardedRef?: React.Ref<any> }

  class WithProvider extends React.Component<Props> {
    render() {
      const { forwardedRef, ...props } = this.props
      return (
        <ApolloProvider client={client}>
          <WrappedComponent {...props} ref={forwardedRef} />
        </ApolloProvider>
      )
    }
  }

  hoistNonReactStatics(WithProvider, WrappedComponent)

  return React.forwardRef((props:P, ref) => (
    <WithProvider {...props} forwardedRef={ref} />
  ))
}

推荐阅读