用于 props 注入的流式高阶组件(同时保留 defaultProps 的可选性)

Flow-typing higher-order components for props injection (while preserving the optionality of defaultProps)

背景:

  1. Flow 关于输入高阶组件的文档描述了props injection and the way of supporting defaultProps,但是建议的代码示例使用了不同的方法,并且没有结合两者的示例。

  2. 自版本 0.72 起,Flow 已弃用推断类型 *(星号)。

问题

我正在尝试结合 Flow 文档中的方法,并键入一个函数,将某个 属性 从 redux 存储注入到提供的组件中。这是我的代码:

import React, { Component, type ComponentType, type ElementConfig } from 'react';
import { connect } from 'react-redux';

import type { State } from 'client/types/redux';

export type InjectedProps = {
  xs: string[]
}

export default function injector<Props, Com: ComponentType<Props>>(
  DecoratedComponent: Com
) : ComponentType<$Diff<ElementConfig<Com>, InjectedProps>> {

  class Decorator extends Component<ElementConfig<Com>> {

    render() {
      return (
        <DecoratedComponent
          {...this.props} // the props will now contain xs from redux
        />
      );
    }

  }

  return connect((state: State)  => ({
    xs: state.xs
  }))(Decorator);
}

这是此代码的简化版本(没有 redux),它给出了与上面 Try Flow 中的代码相同的错误。

请注意 error disappears 如果 * 类型用于 ComponentType

能否请您建议如何在不使用已弃用的 * 类型的情况下正确键入此高阶函数

fixed version你的简化示例。

import React, { Component, type ComponentType, type ElementConfig } from 'react';

type InjectedProps = {
  xs: string[]
}
// notice that InProps must contain an xs property that must be an array of strings
export default function injector<InProps: { xs: string[] }, Com: ComponentType<InProps>, OutProps: $Diff<ElementConfig<Com>, InjectedProps>>(
  DecoratedComponent: Com
) : ComponentType<OutProps> {

  return function decorator(props: OutProps) { // notice OutProps here
      const xs = ['foo']
      return (
        <DecoratedComponent
          {...props}
          xs={xs}
        />
      );
  }
}