如何键入可能有道具的 ReactNode?
How to type ReactNode that may have props?
我已经为此苦苦思索了几个小时,但没有成功。似乎找不到任何其他有帮助的 Whosebug 问题。基本上,我有一个包含两个子节点的组件,如下所示:
<SharedTwoColumns
outer={{ className: "mt4 mb4" }}
gap={<div className="h4 w4" />}
>
<div className={isMobile ? "" : "pa3"}>Left Column</div> // first child
<div className={isMobile ? "" : "pa3"}>Right Column</div> // second child
</SharedTwoColumns>
我正在尝试以某种方式键入“左栏”和“右栏”子级,表明它们都可能有道具,但不一定。我到目前为止是:
const SharedTwoColumns = ({
outer: { className: ocn, ...outer },
children,
gap: {
props: { className: gcn, ...gapProps }
}
}: {
outer: { [x: string]: unknown; className: string };
children: ReactNode;
gap: { props: { [x: string]: unknown; className: string } };
}) => {
...
const [leftColumn, rightColumn]: ReactNode[] = Children.toArray(children);
const {
props: { className: lcn, children: leftColumnChildren, ...leftColumnProps }
}: ReactNode = leftColumn || {}; // TS error happens here when I hover over 'props'
但是,这给了我打字稿错误:
Property 'props' does not exist on type 'boolean | ReactChild | ReactFragment | ReactPortal | null'.
any
有人知道我在解构 leftColumn
的 props 时如何正确输入吗?
不确定这是否回答了您的问题,但您可以创建一个扩展 ReactNode class 的接口。
例如
interface MyNode extends ReactNode {
// ... your custom props here
}
通过这种方式,我相信您可以使用您的自定义界面来输入您的 Columns,在某种程度上,它们拥有 ReactNode 的所有原生 props 加上您的自定义 props
如果我理解正确,您需要为 children 使用 ReactElement
类型,例如:
import React, { ReactElement } from "react";
interface LeftProps {
left: string;
}
const Left = (props: LeftProps) => null;
interface RightProps {
right: string;
}
const Right = (props: RightProps) => null;
interface LayoutProps {
children: [ReactElement<LeftProps>, ReactElement<RightProps>];
}
function Layout({ children }: LayoutProps) {
// You may use React.children.toArray here but it will force you to typecast
// in some cases (like this one with tuple)
const left = children[0].props.left;
const right = children[1].props.right;
return (
<div>
Right: {right} Left: {left}
</div>
);
}
export default function App() {
return (
<Layout>
<Left left="left" />
<Right right="right" />
</Layout>
);
}
我已经为此苦苦思索了几个小时,但没有成功。似乎找不到任何其他有帮助的 Whosebug 问题。基本上,我有一个包含两个子节点的组件,如下所示:
<SharedTwoColumns
outer={{ className: "mt4 mb4" }}
gap={<div className="h4 w4" />}
>
<div className={isMobile ? "" : "pa3"}>Left Column</div> // first child
<div className={isMobile ? "" : "pa3"}>Right Column</div> // second child
</SharedTwoColumns>
我正在尝试以某种方式键入“左栏”和“右栏”子级,表明它们都可能有道具,但不一定。我到目前为止是:
const SharedTwoColumns = ({
outer: { className: ocn, ...outer },
children,
gap: {
props: { className: gcn, ...gapProps }
}
}: {
outer: { [x: string]: unknown; className: string };
children: ReactNode;
gap: { props: { [x: string]: unknown; className: string } };
}) => {
...
const [leftColumn, rightColumn]: ReactNode[] = Children.toArray(children);
const {
props: { className: lcn, children: leftColumnChildren, ...leftColumnProps }
}: ReactNode = leftColumn || {}; // TS error happens here when I hover over 'props'
但是,这给了我打字稿错误:
Property 'props' does not exist on type 'boolean | ReactChild | ReactFragment | ReactPortal | null'.
any
有人知道我在解构 leftColumn
的 props 时如何正确输入吗?
不确定这是否回答了您的问题,但您可以创建一个扩展 ReactNode class 的接口。 例如
interface MyNode extends ReactNode {
// ... your custom props here
}
通过这种方式,我相信您可以使用您的自定义界面来输入您的 Columns,在某种程度上,它们拥有 ReactNode 的所有原生 props 加上您的自定义 props
如果我理解正确,您需要为 children 使用 ReactElement
类型,例如:
import React, { ReactElement } from "react";
interface LeftProps {
left: string;
}
const Left = (props: LeftProps) => null;
interface RightProps {
right: string;
}
const Right = (props: RightProps) => null;
interface LayoutProps {
children: [ReactElement<LeftProps>, ReactElement<RightProps>];
}
function Layout({ children }: LayoutProps) {
// You may use React.children.toArray here but it will force you to typecast
// in some cases (like this one with tuple)
const left = children[0].props.left;
const right = children[1].props.right;
return (
<div>
Right: {right} Left: {left}
</div>
);
}
export default function App() {
return (
<Layout>
<Left left="left" />
<Right right="right" />
</Layout>
);
}