How to Add Type Checking in React

How to Add Type Checking in React

React is a Javascript library and Javascript is a loosely typed language so by default it does not provide any type checking because of which it's very easy to create bugs in your application when we pass the wrong type of data and it will easily crash your application.

There are various static type checkers used in larger application like Flow or Typescript which helps to catch errors at compile time.

But if you want to perform some simple type checking in your React application and don’t want to add annotations at every level like provided by Flow then PropTypes is the preferred way.

PropTypes were part of the React core module itself initially but starting from React version 15.5, it’s moved to prop-types library to keep React library light and small.

You will find prop-types used in a lot of popular libraries for type checking.

Installation

To install the prop-types library execute the following command in terminal:

yarn add prop-types

OR

npm install prop-types

Usage

The library provides a default export so we can name it whatever we want but it’s generally imported as:

import PropTypes from 'prop-types'

If you have installed the React Snippet Extension for React in your IDE as described in my previous article HERE then you can just type impt text to add the import for it.

Import Shortcut

Suppose we have a User component which displayed details of a user:

const User = ({ name, age, location, isMarried }) => {
  return (
    <div className="user">
      <p>Name: {name}</p>
      <p>Age: {age}</p> 
      <p>Location: {location}</p>
      <p>Married: {isMarried ? 'Yes' : 'No'}</p>
    </div>
  );
};

Then we can add type checking to check each of the prop passed to the component is of the correct type as shown below:

User.propTypes = {
 name: PropTypes.string,
 age: PropTypes.number,
 location: PropTypes.string,
 isMarried: PropTypes.bool
};

Note: p is lowercase in User.propTypes and while defining type, it's uppercase like PropTypes.string.

Here, we have used PropTypes for the functional component but it works the same for class components.

Now, suppose If we pass the age as a string to the User component:

const user = {
  name: 'David',
  age: '35',
  location: 'New York',
  isMarried: true
};

ReactDOM.render(<User {...user} />,document.getElementById("root"));

Then you will get a warning in the console when you run the application:

Warning

Here's a Code Sandbox Demo.

So using PropTypes allows us to easily find and fix the issue which might come due to an invalid type before the application is shipped to production.

Apart from number, string and bool, PropTypes supports various other types like:

  • PropTypes.func: Specifies the type to be a function
  • PropTypes.array: Specifies the type to be an array
  • PropTypes.arrayOf: Specifies the type to be an array of a specific type like an array of strings
const names = ['David', 'Jack', 'Mike', 'Tim', 9];
...
<Users names={names} />
...
Users.propTypes = {
  names: PropTypes.arrayOf(PropTypes.string)
};

You will receive a warning in this case because the value 9 in the array is not of type string.

Warning

  • PropTypes.object: Specifies the type to be an object
  • PropTypes.symbol: Specifies the type to be a symbol
  • PropTypes.node: Specifies the type to be a node which means anything which React can render like numbers, strings, elements, DOM elements or an array but not boolean or objects because React does not print boolean values in JSX and for objects, React will throw an error when used in JSX
  • PropTypes.element: Specifies the type to be a React element
User.propTypes = {
 info: PropTypes.element
}
...
<User info={<Info />} />
  • PropTypes.any: Specifies the type to be any value like string, number, boolean, object
  • PropTypes.exact: Specifies the type to be of the exact shape
User.propTypes = {
  info: PropTypes.exact({
    name: PropTypes.string,
    age: PropTypes.number,
    location: PropTypes.string
  })
};

...

const user = {
 name: 'David',
 age: 35,
 location: 'New York'
};

<User info={user} />

If you pass properties different than the one mentioned in the PropType, then you will get a warning.

Warning

  • PropTypes.shape: Specifies the type to be of some shape. It’s similar to exact except that, you can include less or additional props.
User.propTypes = {
  info: PropTypes.shape({
    name: PropTypes.string,
    age: PropTypes.number,
    location: PropTypes.string
  })
};
  • PropTypes.instanceOf: Specifies the type to be an instance of something
User.propTypes = {
 date: PropTypes.instanceOf(Date)
};

...

const today_date = new Date();

<User date={today_date} />
  • PropTypes.oneOf: Specifies the type to be one of the values mentioned
Months.propTypes = {
 day: PropTypes.oneOf(['Monday', 'Tuesday', 'Wendesday'])
};

...

<Months day="Monday" />

If you pass the wrong value, then you will get a warning like this:

Warning

By default every prop is optional. To make any prop as required we can add .required to the PropType.

Image.propTypes = {
 src: PropTypes.string.isRequired
};

Suppose we have an Image component.

const Image = (props) => {
  const { src, alt } = props;
  return (
    <div className="image">
      <img src={src} alt={alt} width="200" height="200" />
    </div>
  );
};

Image.propTypes = {
  src: PropTypes.string.isRequired,
  alt: PropTypes.string.isRequired
};

Then we can display the Image as:

ReactDOM.render(<Image />, document.getElementById("root"));

As you can see, we have just used <Image /> and we are not passing the src and alt props so you will see a warning in the console.

Warning

But, if we pass the required values like this

<Image src="http://unsplash.it/200/200?random" alt="Random image" />

then you will not get a warning message in the console.

Here's a Code Sandbox Demo.

We can add .required to all the PropTypes we have seen above.

Note: The PropType checks are only done in development mode. React will not perform PropType checks when the application is running in production mode.

Thanks for reading!

Want to learn all ES6+ features in detail including let and const, promises, various promise methods, array and object destructuring, arrow functions, async/await, import and export and a whole lot more from scratch?

Check out my Mastering Modern JavaScript book. This book covers all the pre-requisites for learning React and helps you to become better at JavaScript and React.

Check out free preview contents of the book here.

Also, you can check out my free Introduction to React Router course to learn React Router from scratch.

Want to stay up to date with regular content regarding JavaScript, React, Node.js? Follow me on LinkedIn.

Did you find this article valuable?

Support Yogesh Chavan by becoming a sponsor. Any amount is appreciated!