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

Noa*_*oah 5 typescript reactjs 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>
    )
}
Run Code Online (Sandbox Code Playgroud)

以及引用的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> { ... }
Run Code Online (Sandbox Code Playgroud)

我希望SubComponent1是SuperComponent的唯一有效子元素,也就是说,如果我将<SubComponent2 />Type或Other类型作为其子元素,希望Typescript可以引发错误。<SuperComponent>

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

任何的想法 ?如果需要在此处发布任何配置,请随时询问

非常感谢任何想法和解决方案

Mat*_*hen 8

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

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