使用PropType进行Typechecking嵌套对象属性

问题描述 投票:1回答:2

我有以下内容,我想用流注释:

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

但随后流量只是抱怨ph4从未使用过。

javascript reactjs
2个回答
2
投票

所以你想发送一个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).
  }
}

以下是官方文档的说法:

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

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


演示

这是我准备的一个演示。对于您正在寻找的内容,它可能会或可能不会过度,因为验证非常广泛。你可以挑选你需要的那些。您的content的以下验证是(按顺序):

  • 验证道具content已通过。
  • 验证道具contentobject
  • 验证prop content是否具有p的对象属性。
  • 验证prop 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上测试它并做一些嘲弄。尝试更改传递给组件的值,类型和对象属性,并读取控制台输出。

希望这可以帮助。祝好运!


0
投票

我理解这个问题和答案已经很老了,但作为参考,我认为我们应该使用更简单的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;

你也可以通过在类型定义后添加content来制作isRequired或其字段。例如,对于内容:

static propTypes = {
    content: PropTypes.shape({ p: PropTypes.string, h4: PropTypes.string }).isRequired
};
© www.soinside.com 2019 - 2024. All rights reserved.