如何使用 TypeScript 2.3 中新增的支持来限制 TypeScript 中 React Children 的类型?

新手上路,请多包涵

我正在尝试利用 最近在 TypeScript 编译器和 @types/react 中添加的对子项类型的支持,但遇到了困难。我正在使用 TypeScript 2.3.4 版。

假设我有这样的代码:

 interface TabbedViewProps {children?: Tab[]}
export class TabbedView extends React.Component<TabbedViewProps, undefined> {

  render(): JSX.Element {
    return <div>TabbedView</div>;
  }
}

interface TabProps {name: string}
export class Tab extends React.Component<TabProps, undefined> {
  render(): JSX.Element {
    return <div>Tab</div>
  }
}

当我尝试像这样使用这些组件时:

 return <TabbedView>
  <Tab name="Creatures">
    <div>Creatures!</div>
  </Tab>
  <Tab name="Combat">
    <div>Combat!</div>
  </Tab>
</TabbedView>;

我收到如下错误:

 ERROR in ./src/typescript/PlayerView.tsx
(27,12): error TS2322: Type '{ children: Element[]; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<TabbedView> & Readonly<{ children?: ReactNode; }> ...'.
  Type '{ children: Element[]; }' is not assignable to type 'Readonly<TabbedViewProps>'.
    Types of property 'children' are incompatible.
      Type 'Element[]' is not assignable to type 'Tab[] | undefined'.
        Type 'Element[]' is not assignable to type 'Tab[]'.
          Type 'Element' is not assignable to type 'Tab'.
            Property 'render' is missing in type 'Element'.

似乎将孩子的类型推断为 Element[] 而不是 Tab[] 即使这是我使用的唯一类型的孩子。

编辑:限制 子道具 的接口而不是直接限制子组件的类型也很好,因为我需要做的就是从子组件中拉出一些特定的道具。

原文由 Christopher Armstrong 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 720
1 个回答

编辑 2:原来这种方法可以防止警告,但根据评论 TabProps 没有正确检查。

您应该尝试像这样设置接口 TabbedViewProps 的子项

interface TabbedViewProps { children?: React.ReactElement<TabProps>[] }

The idea here is not to tell your TabbedView has an array of Tab , but instead tell your TabbedView he has an array of element 这需要特定的道具。在您的情况下 TabProps

编辑(感谢 Matei):

 interface TabbedViewProps {
    children?: React.ReactElement<TabProps>[] | React.ReactElement<TabProps>
}

原文由 Pierre Ferry 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进