是否可以使用 React 和 TypeScript 将子组件限制为特定组件?

Mag*_*ull 5 typescript reactjs

将 React 与 TypeScript 结合使用,有多种方法可以定义 的类型children,例如将其设置为JSX.ElementorReact.ReactChild或extending PropsWithChildren。但是这样做,是否可以进一步限制React子元素可以是哪个特定元素?

function ListItem() {
  return (
    <li>A list item<li>
  );
}

//--------------------

interface ListProps {
  children: React.ReactChild | React.ReactChild[]
}

function List(props: ListProps) {
  return (
    <ul>
      {props.children} // what if I only want to allow elements of type ListItem here?
    </ul>
  );
}
Run Code Online (Sandbox Code Playgroud)

鉴于上述情况,可以List设置为仅允许类型为 ? 的子级吗ListItem?类似于以下(无效)代码:

interface ListProps {
  children: React.ReactChild<ListItem> | React.ReactChild<ListItem>[]
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*yne 5

你不能像这样限制孩子的反应。

任何 React 函数组件都只是一个具有特定 props 类型并返回的函数JSX.Element。这意味着,如果在将组件传递给子组件之前渲染该组件,那么 React 根本不知道是什么生成了该 JSX,而只是将其传递。

问题是你用<MyComponent>语法渲染组件。所以在那之后,它只是一个 JSX 节点的通用树。


然而,这听起来有点像XY 问题。通常,如果您需要这个,有更好的方法来设计您的 api。

相反,您可以 make 并itemsprop onList它接受一组对象,这些对象将作为 props 传递到组件ListItem内部List

例如:

function ListItem({ children }: { children: React.ReactNode }) {
  return (
    <li>{children}</li>
  );
}

function List(props: { items: string[] }) {
  return (
    <ul>
      {props.items.map((item) => <ListItem>{item}</ListItem> )}
    </ul>
  );
}

const good = <List items={['a', 'b', 'c']} />
Run Code Online (Sandbox Code Playgroud)

在此示例中,您只需输入 props,并且List知道如何生成它自己的子项。

操场