Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
607 views
in Technique[技术] by (71.8m points)

javascript - Typechecking nested object properties with PropType

I have following that i want to annotate with flow:

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

I know how to do the type-check to so that content is of type Object (as shown above), but how can I type-check its properties as well?


Already tried this:

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

But then flow just complains that p and h4 is never used.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So you want to send in an prop that is of type object, which has to have the properties p and h4?

This isn't possible without writing a custom function that does this checking. To do this you would declare your propTypes like so:

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

Here's what the official docs say:

You can also specify a custom validator. It should return an Error object if the validation fails. Don't console.warn or throw [...]

Read more about typechecking with PropTypes on the Official Documentation.


Demo

Here's a demo I prepared. It may or may not be overkill for what you're looking for, since the validation is quite extensive. You may cherry-pick the ones you need. The validations below for your content are (in order):

  • Verify the prop content is passed.
  • Verify the prop content is an object.
  • Verify the prop content has an object property of p.
  • Verify the prop content has an object property of h1.
  • Verify the object property content.p is a string.
  • Verify the object property content.h1 is a string.

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>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...