{"id":7297,"date":"2019-08-17T17:20:33","date_gmt":"2019-08-17T17:20:33","guid":{"rendered":"http:\/\/putridparrot.com\/blog\/?p=7297"},"modified":"2019-08-17T17:20:33","modified_gmt":"2019-08-17T17:20:33","slug":"proptypes","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/proptypes\/","title":{"rendered":"PropTypes"},"content":{"rendered":"<p>PropTypes are used in React components to specify type information etc. If (as I am) you&#8217;re using TypeScript then for the most part such type extra information is not really required as we get a similar functionality via TypeScript interfaces. However, you&#8217;ll see these used a lot in JSX files where. not only can you define the expected types, but also the expected values.<\/p>\n<p>To install<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nyarn add prop-types\r\n<\/pre>\n<p>PropTypes are only available in <em>development mode<\/em> which makes sense for the most part, so you would still need runtime checking on values supplied by the end user or the likes.<\/p>\n<p>The usual way to write our propTypes in a JSX file is like this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nimport React from 'react';\r\nimport PropTypes from 'prop-types';\r\n\r\nclass Company extends React.Component {\r\n    render() {\r\n        return &lt;div&gt; \r\n        &lt;h1&gt;{this.props.name}&lt;\/h1&gt;\r\n        {this.props.country ? &lt;p&gt;Country: {this.props.country}&lt;\/p&gt; : null}\r\n        {this.props.size ? &lt;p&gt;Size: {this.props.size}&lt;\/p&gt; : null}\r\n        &lt;\/div&gt;;   \r\n    }\r\n}\r\n\r\nCompany.propTypes = {\r\n  name: PropTypes.string,\r\n  country: PropTypes.string,\r\n  size: PropTypes.oneOf(&#x5B;'small', 'medium', 'large']),\r\n};\r\n\r\nexport default Company;\r\n<\/pre>\n<p>If we now change App.tsx to just have this<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\nconst App: React.FC = () =&gt; {\r\n  return (\r\n    &lt;Company name=&quot;My Company&quot; size=&quot;mega&quot; \/&gt;\r\n  );\r\n}\r\n<\/pre>\n<p>You&#8217;ll find this runs but an error log in your preferred browser debug tools will show that &#8220;maga&#8221; is not a valid option, because obviously it wasn&#8217;t oneOf the supplied options.<\/p>\n<p>Let&#8217;s now change the Company.jsx file to a .tsx extension.<\/p>\n<p>This will fail to transpile with an error such as &#8220;Type &#8216;{ name: string; size: string; }&#8217; is not assignable to type &#8216;IntrinsicAttributes &#038; IntrinsicClassAttributes<Company> &#038; Readonly<{}> &#038; Readonly<{ children?: ReactNode; }>&#8216;.&#8221;<\/p>\n<p>Instead, we can use interfaces within TypeScript to handle the type checking at transpile time, hence this code gives us a similar set of function to the JSX version<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\r\ntype Size = 'small' | 'medium' | 'large';\r\n\r\ninterface CompanyProps {\r\n  name?: string,\r\n  country?: string,\r\n  size?: Size\r\n}\r\n\r\nclass Company extends React.Component&lt;CompanyProps&gt; {\r\n\r\n    render() {\r\n        return &lt;div&gt; \r\n        &lt;h1&gt;{this.props.name}&lt;\/h1&gt;\r\n        {this.props.country ? &lt;p&gt;Country: {this.props.country}&lt;\/p&gt; : null}\r\n        {this.props.size ? &lt;p&gt;Size: {this.props.size}&lt;\/p&gt; : null}\r\n        &lt;\/div&gt;;   \r\n    }\r\n}\r\n<\/pre>\n<p><strong>References<\/strong><\/p>\n<p><a href=\"https:\/\/github.com\/facebook\/prop-types\" rel=\"noopener noreferrer\" target=\"_blank\">prop-types<\/a><br \/>\n<a href=\"https:\/\/github.com\/joelday\/ts-proptypes-transformer\" rel=\"noopener noreferrer\" target=\"_blank\">ts-proptypes-transformer<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>PropTypes are used in React components to specify type information etc. If (as I am) you&#8217;re using TypeScript then for the most part such type extra information is not really required as we get a similar functionality via TypeScript interfaces. However, you&#8217;ll see these used a lot in JSX files where. not only can you [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[243],"tags":[],"class_list":["post-7297","post","type-post","status-publish","format-standard","hentry","category-react"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7297","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=7297"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7297\/revisions"}],"predecessor-version":[{"id":7358,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/7297\/revisions\/7358"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=7297"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=7297"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=7297"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}