网站搜索

reactjs - ReactTS:如何在“容器组件”中嵌套子组件?


我正在使用 Typescript 在 React 中创建可重用的前端组件,我在一个功能上遇到了困难,这在传统包中似乎是可能的。

我希望能够在"容器组件"中嵌套某种类型的子组件,并在主组件中检索每一组子组件。

我尝试了很多类型的子组件属性,比如:

export type DataGridChild = typeof DataGridColumns | typeof DataGridActions;

export type DataGridProps<T> = BaseProps & {
    data: T[];
    children: React.ReactElement<DataGridChild> | React.ReactElement<DataGridChild>[];
}

但是,我找不到方法来以正确的类型检索每个子项。此外,例如,如果我将 DataGridColumn 容器组件添加两次,TypeScript 也不会抛出任何错误。

最后,我希望有一个可以与这种代码一起使用的组件:

<DataGrid data={persons}>
  <DataGridColumns>
    <DataGridColumn field="name" />
    <DataGridColumn field="age" />
    <DataGridColumn field="weight" />
    <DataGridColumn field="birthDate" type="date" />
  </DataGridColumns>
  <DataGridActions>
    <DataGridAction text="Action 1" onClick={(rd) => console.log("Action 1 clicked")} />
  </DataGridActions>
</DataGrid>

我在网上找不到任何东西。有人知道该怎么做吗?

非常感谢 :)

答案#1

既然你正在使用 Union,最终你将做的事情与所谓的经典包一样:Union 缩小。更多内容请参见 使用 Union 类型。[typescriptlang.org]


让我们来分解这段代码。你为 Union 声明了一个类型别名,叫做 DataGridChild:

typeof DataGridColumns | typeof DataGridActions

因此,无论何处使用 DataGridChild,都期望使用 typeof DataGridColumns 或 typeof DataGridActions。既然这是选择,就要预期执行 缩小类型。

接下来,你声明了一个类型别名 DataGridProps<T>,用于由扩展类型 BaseProps 并包含两个属性构建的匿名类型:

BaseProps & {
    data: T[];
    children: React.ReactElement<DataGridChild> | React.ReactElement<DataGridChild>[];
}
  • 数据:一个类型为 T 的对象数组。
  • children:一种 Union 类型,其值可以是以下任何一个:

    React.ReactElement<DataGridChild>
    React.ReactElement<DataGridChild>
  • 或者一个 Array:同样,因为这是选择,所以也要准备执行 收窄。


现在解释已经完成,你应该能够回答你的问题了。

然而,为了后世,让我们一起回答他们。

我找不到一种方法来以正确的类型获取每个子项。

执行 Union 缩小。

此外,如果我例如两次添加 DataGridColumn 容器组件,TypeScript 不会抛出任何错误。

你只定义了一个类型别名 DataGridProps<T>,我怀疑你用它来声明和定义 DataGrid 元素的属性。

如果你没有为 DataGridColumns 或 DataGridActions 定义 prop Interface,那么它们的 props 会隐式成为 any 类型。因此,TypeScript 不会提供类型检查,因此不会有类型检查错误。为组件定义 Interface,可以为组件提供更细粒度的控制和类型安全。