用打字稿反应组件子类型检查

时间:2018-10-10 03:06:55

标签: reactjs typescript tsx

这是场景:

我有一个自定义组件:

class MyComponent extends React.Component {
  render () {
    return (
      <SuperComponent>
        <SubComponent1 />  // <- valid child
      </SuperComponent>
    )
}

class MyComponent extends React.Component {
  render () {
    return (
      <SuperComponent>
        <SubComponent2 />  // <- No! It's not right shape
      </SuperComponent>
    )
}

以及引用的SuperComponent和SubComponent1是:

interface superPropsType = {
  children: ReactElement<subPropsType1>
}
class SuperComponent extends React.Component<superPropsType> { ... }


interface subPropsType1 = {
  name: string
}
class SubComponent1 extends React.Component<subPropsType1> { ... }


interface subPropsType2 = {
  title: string
}
class SubComponent2 extends React.Component<subPropsType2> { ... }

我希望SubComponent1是SuperComponent的唯一有效子项,也就是说,如果我将<SubComponent2 />或其他类型作为<SuperComponent>的子项,我希望打字稿可以抛出错误

似乎打字稿仅检查的子项应具有ReactElement的类型,但ts不会检查该子项的道具形状(即subPropsType1),也就是说,如果我将字符串或数字放置为ts将成为SuperComponent的子代,ts会抱怨类型要求不满足,但是如果我在此处放置任何jsx标记(它将被转换为ReactElement),ts会保持沉默

有什么主意吗?如果需要在此处发布任何配置,请随时询问

真的很感谢任何想法和解决方案

2 个答案:

答案 0 :(得分:7)

从TypeScript 3.1开始,所有JSX元素都被硬编码为JSX.Element类型,因此无法接受某些JSX元素,而不能接受其他元素。如果要进行这种检查,则必须放弃JSX语法,定义自己的元素工厂函数,该函数包装React.createElement,但为不同的组件类型返回不同的元素类型,并手动写入对该工厂函数的调用。

an open suggestion,它可能在TypeScript 3.2(将于2018年11月下旬发布)之后立即实施,以便TypeScript根据工厂函数的实际返回类型为JSX元素分配类型。给定的组件类型。如果实现了这一点,您将能够定义自己的工厂函数,该工厂函数包装React.createElement并使用jsxFactory编译器选项进行指定,您将获得其他类型信息。也许@types/react甚至会改变,以便React.createElement提供更丰富的类型信息,如果可以做到的话,不会对不关心功能的项目造成有害影响;我们将不得不拭目以待。

答案 1 :(得分:0)

我可能会声明SuperPropsType.children为:

children: React.ReactElement<SubPropsType1> | React.ReactElement<SubPropsType1>[];

要考虑有一个孩子和多个孩子的可能性。

在任何情况下,正如已经指出的那样,这将无法按预期进行。

您可以做的是声明一个道具,比方说subComponentProps: SubPropsType1[],以传递需要创建这些SubComponent1(而不是它们的JSX)的道具,并在{{1 }}:

SuperComponent