PropTypes

PropTypes are used in React components to specify type information etc. If (as I am) you’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’ll see these used a lot in JSX files where. not only can you define the expected types, but also the expected values.

To install

yarn add prop-types

PropTypes are only available in development mode which makes sense for the most part, so you would still need runtime checking on values supplied by the end user or the likes.

The usual way to write our propTypes in a JSX file is like this

import React from 'react';
import PropTypes from 'prop-types';

class Company extends React.Component {
    render() {
        return <div> 
        <h1>{this.props.name}</h1>
        {this.props.country ? <p>Country: {this.props.country}</p> : null}
        {this.props.size ? <p>Size: {this.props.size}</p> : null}
        </div>;   
    }
}

Company.propTypes = {
  name: PropTypes.string,
  country: PropTypes.string,
  size: PropTypes.oneOf(['small', 'medium', 'large']),
};

export default Company;

If we now change App.tsx to just have this

const App: React.FC = () => {
  return (
    <Company name="My Company" size="mega" />
  );
}

You’ll find this runs but an error log in your preferred browser debug tools will show that “maga” is not a valid option, because obviously it wasn’t oneOf the supplied options.

Let’s now change the Company.jsx file to a .tsx extension.

This will fail to transpile with an error such as “Type ‘{ name: string; size: string; }’ is not assignable to type ‘IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{}> & Readonly<{ children?: ReactNode; }>‘.”

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

type Size = 'small' | 'medium' | 'large';

interface CompanyProps {
  name?: string,
  country?: string,
  size?: Size
}

class Company extends React.Component<CompanyProps> {

    render() {
        return <div> 
        <h1>{this.props.name}</h1>
        {this.props.country ? <p>Country: {this.props.country}</p> : null}
        {this.props.size ? <p>Size: {this.props.size}</p> : null}
        </div>;   
    }
}

References

prop-types
ts-proptypes-transformer