Skip Main Navigation
Ben IlegboduBen Ilegbodu

React Prop Types with TypeScript

A guide comparing React Prop Types to their equivalent TypeScript definitions

Thursday, June 11, 2020 · 2 min read

If you're wanting to use TypeScript with React, the first thing you need to figure out is how to define the prop types in TypeScript. In vanilla React, defining the prop types (via the prop-types) package is optional. But with TypeScript, everything must be typed, either implicitly or explicitly.

Below are mappings from PropTypes to TypeScript types that you can use as a resource.

Primitive types

Prop types:

Example.propTypes = {
  message: PropTypes.string,
  count: PropTypes.number,
  disabled: PropTypes.bool,
  level: PropTypes.symbol,
}

TypeScript:

interface Props {
  message: string
  count: number
  disabled: boolean
  level: Symbol
}

Special types

Prop types:

Example.propTypes = {
  error: PropTypes.instanceOf(Error),
  children: PropTypes.node,
  status: PropTypes.oneOf(['inactive', 'inProgress', 'success', 'failed']),
  value: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.instanceOf(Error),
  ]),
}

TypeScript:

interface Props {
  error: Error
  children: React.ReactNode
  status: 'inactive' | 'inProgress' | 'success' | 'failed'
  value: string | number | Error
}

Array & object types

Prop types:

Example.propTypes = {
  style: PropTypes.shape({
    color: PropTypes.string,
    fontSize: PropTypes.number,
  }),
  person: PropTypes.exact({
    name: PropTypes.string,
    age: PropTypes.number,
    employed: PropTypes.bool,
    status: PropTypes.oneOf([
      'single',
      'dating',
      'engaged',
      'married',
      'divorced',
      'widowed',
      'other',
    ]),
  }),
  names: PropTypes.arrayOf(PropTypes.string),
  items: PropTypes.arrayOf(
    PropTypes.shape({
      id: PropTypes.number,
      title: PropTypes.string,
      active: PropTypes.boolean,
    }),
  ),
}

TypeScript:

interface Props {
  style: {
    color: string
    fontSize: number
  }
  person: {
    name: string
    age: number
    employed: boolean
    status:
      | 'single'
      | 'dating'
      | 'engaged'
      | 'married'
      | 'divorced'
      | 'widowed'
      | 'other'
  }
  names: string[]
  items: {
    id: number
    title: string
    active: boolean
  }[]
}

NOTE: PropTypes.shape() allows for additional properties outside of those to be included in the object, so technically the equivalent TypeScript type is an index type. But generally, when folks use PropTypes.shape() they really mean PropTypes.exact().

Function types

Prop types:

Example.propTypes = {
  onClick: PropTypes.func,
  onChange: PropTypes.func,
  onSelect: PropTypes.func,
}

TypeScript:

interface Props {
  onClick: () => void
  onChange: (val: string) => void
  onSelect: (id: string, val: number) => void
}

NOTE: As you can see, function prop types do not define their interface, while TypeScript functions have an explicit definition of their params and return value.

Required vs. Optional

Don't forget! With PropTypes, the props are all optional by default and you have to use .isRequired. With TypeScript, all props are required by default, so you need to mark them as optional using ?:

Prop Types:

Example.propTypes = {
  description: PropTypes.string.isRequired,
  isActive: PropTypes.bool,
}

TypeScript:

interface Props {
  description: string
  isActive?: boolean
}

Attend a minishop!

Are you interested in learning more about how you can leverage TypeScript within React to eliminate bugs and feel more confident about your code? I have a TypeScript for React Developers minishop that you can register for in order to learn more!

In addition to diving deeper into type-checking props, we'll get hands-on experience type-checking common hooks (useState, useEffect, etc), forms and custom events, and many other features that will help you write quality code. Register today!

Keep learning my friends. 🤓

Subscribe to the Newsletter

Get notified about new blog posts, minishops & other goodies


Hi, I'm Ben Ilegbodu. 👋🏾

I'm a Christian, husband, and father of 3, with 15+ years of professional experience developing user interfaces for the Web. I'm a Google Developer Expert Frontend Architect at Stitch Fix, and frontend development teacher. I love helping developers level up their frontend skills.

Discuss on Twitter // Edit on GitHub