reactjs - 键入 React 组件工厂函数

标签 reactjs typescript factory type-constraints tsx

鉴于类型

type EnumerableComponentFactory = <C, I>(config: {
  Container: React.ComponentType<C>;
  Item: React.ComponentType<I>;
}) => React.FC<{ items: I[] }>;
具有以下实现
const Enumerable: EnumerableComponentFactory =
  ({ Container, Item }) =>
  ({ items }) =>
    (
      <Container>
        {items.map((props, index) => (
          <Item key={index} {...props} />
        ))}
      </Container>
    );
和预期用途
const UnorderedList = Enumerable({
  Container: ({ children }) => <ul>{children}</ul>,
  Item: ({ title }: { title: string }) => <li>{title}</li>,
});

<UnorderedList items=[{title: "Something"}] />
我观察到以下 TypeScript 错误
Type '{ children: Element[]; }' is not assignable to type 'C'.
  'C' could be instantiated with an arbitrary type which could be unrelated to '{ children: Element[]; }'.ts(2322)
这引出了我的问题:我需要设置什么类型的约束来解决这个错误?
我试图改变类型如下:
type EnumerableComponentFactory = <C extends { children?: Element[] }, I>(config: {
  Container: ComponentType<C>;
  Item: ComponentType<I>;
}) => (props: { items: I[] }) => ReturnType<FC<I>>;
但这会产生一个更加神秘的错误消息,为了简洁起见,我将省略它。

附言该函数本身实际上完全符合预期。只是编译器出了问题。

最佳答案

是否需要保留C通用参数?

import React, { FC, ComponentType, PropsWithChildren } from "react";

type EnumerableComponentFactory = <I>(config: {
  // or Container: FC<{ children: JSX.Element[] }>;
  Container: FC<PropsWithChildren<object>>;
  Item: ComponentType<I>;
}) => FC<{ items: I[] }>;

const Enumerable: EnumerableComponentFactory =
  ({ Container, Item }) =>
  ({ items }) =>
    (
      <Container>
        {items.map((props, index) => (
          <Item key={index} {...props} />
        ))}
      </Container>
    );

const UnorderedList = Enumerable({
  Container: ({ children }) => <ul>{children}</ul>,
  Item: ({ title }: { title: string }) => <li>{title}</li>,
});

const result = <UnorderedList items={[{ title: "Something" }]} />;

关于reactjs - 键入 React 组件工厂函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68397897/

相关文章:

reactjs - 使用react-leaflet渲染GeoJSON

reactjs - React-Bootstrap 表单组件

typescript - 我可以将两种类型 <K, V> 转换为具有这些类型的单个字段的对象类型吗?

javascript - Angular/ typescript : arrays in typescript changing when an independent element got changed

javascript - 如何调用外部url?

c# - MEF ExportFactory<T> - 如何在长时间运行的应用程序中正确处理?

caSTLe-windsor - 温莎城堡 : A better way to implement 2 levels of (nested) factories?

reactjs - prerender.io .htaccess 变量 - Reactjs CRA

c# - 如何使用工厂使用 Autofac 解析接口(interface)

reactjs - React Material UI BottomNavigation 组件路由问题