gpt4 book ai didi

reactjs - 使用 TypeScript 将具有类型字段的数据对象映射到特定的 React 组件

转载 作者:行者123 更新时间:2023-12-05 06:59:37 25 4
gpt4 key购买 nike

我们在节点的(树)结构中有内容,其中每个节点都有一个类型

type NodeType = "text" | "image";

interface Node<T extends NodeType> {
type: T;
}

为简单起见,假设我们得到的内容不是树,而是不同类型的节点数组:

type Content = Nodes[NodeType][];

const content: Content = [{ type: "text" }, { type: "image" }];

现在我想遍历此内容并根据 Nodetype 呈现不同的 ReactComponent:

function App() {
const contents: Nodes[NodeType][] = [{ type: "text" }, { type: "image" }];
return (
<div>
{contents.map((node) => {
const Component = getComponent(node);
return <Component node={node} />;
})}
</div>
);
}

我在实现 getComponent 函数时遇到了很大的问题

function getComponent<N extends Node>(node: N): React.FC<{ node: N }>;

我无法让 TypeScript 将不同类型的 Node 正确映射到接受这些 NodeFC

所以我希望实现的是获得一个函数,该函数将接受 textimage 节点并返回一个 FC接受 node 作为 prop,所以

getComponent(node: Node<"text">): React.FC<{ node: Node<"text">}>;
getComponent(node: Node<"image">): React.FC<{ node: Node<"image">}>;

我在此处创建了一个代码沙盒和我的实现

https://codesandbox.io/s/peaceful-silence-90glv?file=/src/App.tsx

我还是会复制粘贴到这里

import React, { ReactElement } from "react";

type NodeType = "text" | "image";

interface Node<T extends NodeType> {
type: T;
}

type Nodes = {
[T in NodeType]: Node<T>;
};

type Components = {
[T in NodeType]: NodeFC<T>;
};

type NodeFC<T extends NodeType> = (props: { node: Nodes[T] }) => ReactElement;

const components: Components = {
text: ({ node }) => <pre>{node.type}</pre>,
image: ({ node }) => <pre>{node.type}</pre>
};

function getComponent<N extends Node<NodeType>>(
node: N
): N extends Node<infer T> ? NodeFC<T> : never {
return components[node.type];
// ^^^^^^^^^^^^^^^^^^^^^ this does not work
}

const Content = (props: { node: Node<NodeType> }) => {
const Component = getComponent(props.node);
return <Component node={props.node} />;
};

export default function App() {
const contents: Nodes[NodeType][] = [{ type: "text" }, { type: "image" }];
return (
<div>
{contents.map((node) => (
<Content node={node} />
))}
</div>
);
}

第 27 行 抛出以下错误

return components[node.type];
Type 'NodeFC<"text"> | NodeFC<"image">' is not assignable to type 'N extends Node<infer T> ? NodeFC<T> : never'.
Type 'NodeFC<"text">' is not assignable to type 'N extends Node<infer T> ? NodeFC<T> : never'.ts(2322)

我已经尝试了很多实现,但我仍然无法将具有特定 typeNode 映射到特定的 React Component接受 Node 作为 Prop.

最佳答案

Twitter 上的一位用户解决了问题:

https://twitter.com/mediaquery/status/1316375077735337989

以下是他所做更改的差异:

https://www.diffchecker.com/uGdtWP3I

enter image description here

以及CodeSandbox上的完整代码:

https://codesandbox.io/s/fervent-framework-mwo7b?file=/src/App.tsx

import React, { ReactElement } from "react";

type NodeType = "text" | "image";

interface Node<T extends NodeType> {
type: T;
}

type Nodes = {
[T in NodeType]: Node<T>;
};

type Components<T extends NodeType> = {
[key in T]: NodeFC<T>;
};

type NodeFC<T extends NodeType> = (props: { node: Nodes[T] }) => ReactElement;

const components: Components<NodeType> = {
text: ({ node }) => <pre>{node.type}</pre>,
image: ({ node }) => <pre>{node.type}</pre>
};

function getComponent<N extends Node<NodeType>>(
node: N
): NodeFC<N['type']> {
return components[node.type];
}

const Content = (props: { node: Node<NodeType> }) => {
const Component = getComponent(props.node);
return <Component node={props.node} />;
};

export default function App() {
const contents: Nodes[NodeType][] = [{ type: "text" }, { type: "image" }];
return (
<div>
{contents.map((node) => (
<Content node={node} />
))}
</div>
);
}

关于reactjs - 使用 TypeScript 将具有类型字段的数据对象映射到特定的 React 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64353812/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com