用打字稿反应组件子类型检查 [英] React Component children typecheck with typescript

查看:174
本文介绍了用打字稿反应组件子类型检查的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是场景:

我有一个自定义组件:

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),也就是说,如果我将字符串或数字放置为SuperComponent的子代,ts会抱怨类型要求不满足,但是如果我在此处放置任何jsx标记(它将被转换为ReactElement),ts会保持沉默

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

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

解决方案

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

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

Here is the scenario:

I have a custom component:

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>
    )
}

and the referenced SuperComponent and SubComponent1 are:

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> { ... }

I want SubComponent1 to be the only valid child of SuperComponent, that is, I wish typescript can throw an error if I place <SubComponent2 /> or Other types as child of <SuperComponent>

It seems like typescript only check that the child of should have the type of ReactElement, but ts doesn't check the shape of props of that child (which is subPropsType1), that is, if I place a string or number as child of SuperComponent, ts will complaints that type requirement doesn't meet, but if I place any jsx tag here(which will transpiled to ReactElement), ts will keep silent

Any idea ? And if any configs are required to post here, please don't hesitate to ask

Really appreciate any idea and solution

解决方案

As of TypeScript 3.1, all JSX elements are hard-coded to have the JSX.Element type, so there's no way to accept certain JSX elements and not others. If you wanted that kind of checking, you would have to give up the JSX syntax, define your own element factory function that wraps React.createElement but returns different element types for different component types, and write calls to that factory function manually.

There is an open suggestion, which might be implemented as soon as TypeScript 3.2 (to be released in late November 2018), for TypeScript to assign types to JSX elements based on the actual return type of the factory function for the given component type. If that gets implemented, you'll be able to define your own factory function that wraps React.createElement and specify it with the jsxFactory compiler option, and you'll get the additional type information. Or maybe @types/react will even change so that React.createElement provides richer type information, if that can be done without harmful consequences to projects that don't care about the functionality; we'll have to wait and see.

这篇关于用打字稿反应组件子类型检查的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆