如何制作具有泛型类型的功能性 React 组件?

How to make a functional React component with generic type?

我正在尝试制作一个 React 组件,它接受一个通用类型参数,该参数将成为其 prop 类型的一部分。

我想要一个看起来像这样的解决方案:

interface TestProps<T> {
  value: T;
  onChange: (newValue: T) => void;
}

const Test: React.FC<TestProps<T>> = (props) => (
  <span>{props.value}</span>
);

我看到 TypeScript 2.9 对此提供了支持,我正在使用 4.3.5。

它的用法如下所示:

const Usage: React.FC = () => (
  <div>
    <Test<Obj>
      value={{ name: 'test' }}
      onChange={(newValue) => {
        console.log(newValue.name);
      }}
    />
  </div>
);

代码沙箱:https://codesandbox.io/s/react-typescript-playground-forked-8hu13?file=/src/index.tsx

最简单的方法是使通用 FC 成为常规函数,而不是箭头函数。 (React.PropsWithChildren<> 模拟了 React.FC 对您的 props 类型的作用。)

function Test<T>(props: React.PropsWithChildren<TestProps<T>>) {
    return <span>Some component logic</span>;
}

您需要以这种方式重写您的 Test 组件

const Test= <T,>(props:TestProps<T>) => (
    <span>Some component logic</span>
);

Can you show the same with React.FC<TestProps>? It is impossible to do with FC.

这是FC实现:

interface FunctionComponent<P = {}> {
  (props: PropsWithChildren<P>, context?: any): ReactElement<any, any> | null;
  // ... other static properties
}

您可能已经注意到,FC 是函数类型,而不是道具类型。

更新

您可以创建高阶函数,但我不确定是否值得

const WithGeneric = <T,>(): React.FC<TestProps<T>> =>
  (props: TestProps<T>) => (
    <span>Some component logic</span>
  );
const Test = WithGeneric<Obj>()