【问题标题】:Typechecking nested object properties with PropType使用 PropType 对嵌套对象属性进行类型检查
【发布时间】:2016-10-28 07:19:58
【问题描述】:

我有以下我想用流注释:

type PropType = {
  content: Object
};

export const DialogContent = ({ content }: PropType) => (
  <div>
    <p className={cn('text-head')}>{content.h4}</p>
    <p className={cn('text-bottom')}>
      {content.p}
    </p>
  </div>
);

我知道如何进行类型检查以使content 的类型为Object(如上所示),但我如何也可以对其属性进行类型检查?


已经试过了:

  type PropType = {
  content: {
    p: string,
    h4: string
  }
};

但随后 flow 只是抱怨从未使用过 ph4

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    所以你想发送一个object 类型的道具,它必须具有ph4 的属性?

    如果不编写执行此检查的自定义函数,这是不可能的。为此,您可以像这样声明您的propTypes

    propTypes: {
      content: function(props, propName, componentName) {
        //do your validation here. 
        //Return an Error if something's wrong, otherwise don't return anything (or return null).
      }
    }
    

    官方文档是这样说的:

    您还可以指定自定义验证器。它应该返回一个错误 如果验证失败,则对象。不要console.warn 或抛出 [...]

    Official Documentation 上阅读有关使用 PropTypes 进行类型检查的更多信息。


    演示

    这是我准备的演示。由于验证非常广泛,因此对于您正在寻找的东西可能会也可能不会过分杀伤力。你可以挑选你需要的那些。以下对您的content 的验证是(按顺序):

    • 验证 prop content 是否通过。
    • 验证属性contentobject
    • 验证道具content 的对象属性为p
    • 验证属性content 的对象属性为h1
    • 验证对象属性content.pstring
    • 验证对象属性content.h1string

    var DialogContent = React.createClass({
      propTypes: {
        content: function(props, propName, componentName) {
          if (!props.content) {
            return new Error(
              'Required prop `' + propName + '` was not specified in `' + componentName + '`.'
            );
          } else if (typeof props.content !== 'object') {
            return new Error(
              'Invalid prop `' + propName + '` of type `' + typeof props.content + '` supplied to `' + componentName + '`, expected `object`.'
            );
          } else if (!props.content.p) {
            return new Error(
              'Required prop `p` of object `' + propName + '` was not specified in `' + componentName + '`.'
            );
          } else if (!props.content.h1) {
            return new Error(
              'Required prop `h1` of object `' + propName + '` was not specified in `' + componentName + '`.'
            );
          } else if (typeof props.content.p !== 'string') {
            return new Error(
              'Invalid object property `p` of prop `' + propName + '` of type `' + typeof props.content.p + '` supplied to `' + componentName + '`, expected `string`.'
            );
          } else if (typeof props.content.h1 !== 'string') {
            return new Error(
              'Invalid object property `h1` of prop `' + propName + '` of type `' + typeof props.content.h1 + '` supplied to `' + componentName + '`, expected `string`.'
            );
          }
        }
      },
    
      render: function() {
        return <div>My DialogContent Component</div>;
      }
    });
    
    var obj = {
      p: "foo",
      h1: "bar"
    };
    
    ReactDOM.render(<DialogContent content={obj} />,
      document.getElementById('container')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    
    <div id="container"></div>

    您也可以在Fiddle 上对其进行测试并进行一些模拟。尝试更改传递给组件的值、类型和对象属性并读取控制台输出。

    希望这会有所帮助。祝你好运!

    【讨论】:

      【解决方案2】:

      我知道这个问题和答案已经很老了,但作为参考,我认为我们应该添加当前的标准方法来使用prop-types 进行类型检查,这要简单得多:

      import PropTypes from 'prop-types';
      
      class DialogContent extends React.Component {
      
        static propTypes = {
          content: PropTypes.shape({ p: PropTypes.string, h4: PropTypes.string })
        };
      
        render() {
          const { p, h4 } = this.props.content;
      
          return (
            <div>
              <p className='text-head'>{h4}</p>
              <p className='text-bottom'>
                {p}
              </p>
            </div>
          )
        }
      }
      
      export default DialogContent;
      

      您还可以通过在类型定义后添加isRequired 来使content 或其字段成为必填字段。例如内容:

      static propTypes = {
          content: PropTypes.shape({ p: PropTypes.string, h4: PropTypes.string }).isRequired
      };
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-07-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-04
        • 2016-08-29
        相关资源
        最近更新 更多