如何解决键入 React 组件工厂函数
给定类型
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" }]} />;
,
我能够更改您的代码以使其正常工作,同时还接受其他要传递给容器的道具:
type EnumerableComponentFactory = <C,I>(config: {
Container: React.ComponentType<C & { children: React.ReactNode[] }>;
Item: React.ComponentType<I>;
}) => React.ComponentType<C & { items: I[] }>;
const Enumerable: EnumerableComponentFactory = ({ Container,Item }) => (
props
) => (
<Container {...props}>
{props.items.map((props,index) => (
<Item key={index} {...props} />
))}
</Container>
);
这允许例如这个:
const ContainerWithBorder: React.ComponentType<{ color: string }> = (props) => (
<div style={{ border: `2px solid ${props.color}` }}>
<ul>{props.children}</ul>
</div>
);
const ComplexList = Enumerable({
Container: ContainerWithBorder,Item: ({ title }: { title: string }) => <li>{title}</li>
});
<ComplexList items={[{ title: "Something" }]} color="red" />
ComplexList
组件带有 color
属性的输入/智能感知。
可以找到带有原始示例和 ComplexList
示例的游乐场 here。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。