Tutorial

How To Use Typescript with Create React App

DevelopmentJavaScriptReactTypeScript

Introduction

Create React App provides you with a set of essential packages and configurations to start building a React application. Version 2.0 introduced official TypeScript support. This allowed for JavaScript users to write with TypeScript conventions in the React frontend framework. TypeScript is a powerful tool that helps write safer, self-documenting code, allowing developers to catch bugs faster.

In this article, you will set up a React app with TypeScript using Create React App.

Prerequisites

To follow along with this article, you will need:

This tutorial was verified with Node v15.13.0, npm v7.8.0, react-scripts v4.0.3, react v17.0.2, and typescript v4.2.3.

Starting a TypeScript Create React App

First, open your terminal window and navigate to the directory you want to build your project in.

Then, use create-react-app with the --template typescript flag:

  • npx create-react-app cra-typescript-example --template typescript

Your terminal window will display an initial message:

Creating a new React app in [..]/cra-typescript-example.

Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts with cra-template-typescript...

The --template typescript flag instructs the Create React App script to build using cra-template-typescript template. This will add the main TypeScript package.

Note: In previous versions of Create React App, it was possible to use the --typescript flag, but this option has since been deprecated.

Once installation is complete, you will have a new React application with TypeScript support. Navigate to your project directory and open it in your code editor.

Examining the tsconfig.json File

You may have noticed that your terminal window displayed the following message:

We detected TypeScript in your project (src/App.test.tsx) and created a tsconfig.json file for you.

Your tsconfig.json has been populated with default values.

The tsconfig.json file is used to configure TypeScript projects, similar to how package.json is for JavaScript projects.

The tsconfig.json generated by Create React App will resemble the following:

tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx"
  },
  "include": [
    "src"
  ]
}

This configuration establishes several compilation rules and versions of ECMAScript to compile to.

Examining the App.tsx File

Now, let’s open the App.tsx file:

src/App.tsx
import React from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.tsx</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
    </div>
  );
}

export default App;

If you have used Create React App before, you may have noticed that this is very similar to the App.js file that Create React App generates for non-TypeScript builds. You get the same base as the JavaScript projects, but TypeScript support has been built into the configuration.

Next, let’s create a TypeScript component and explore the benefits it can provide.

Creating a TypeScript Component

Start by creating a functional component in the App.tsx file:

function MyMessage({ message }) {
  return <div>My message is: {message}</div>;
}

This code will take a message value from the props. It will render a div with the text My message is: and the message value.

Now let’s add some TypeScript to tell this function that its message parameter should be a string.

If you’re familiar with TypeScript, you may think you should try to append message: string to message. However, what you have to do in this situation is define the types for all props as an object.

There are a few ways you can accomplish this.

Defining the types inline:

function MyMessage({ message }: { message: string }) {
  return <div>My message is: {message}</div>;
}

Defining a props object:

function MyMessage(props: { message: string }) {
  return <div>My message is: {props.message}</div>;
}

Using a separate interface:

interface MyMessageProps {
  message: string;
}

function MyMessage(props: MyMessageProps) {
  return <div>My message is: {props.message}</div>;
}

You can create an interface and move that into a separate file so your types can live elsewhere.

This may seem like a lot of writing, so let’s see what we gain from writing a bit more.

We’ve told this component that it only accepts a string as the message parameter. Now let’s try using this inside our App component.

Using TypeScript Components

Let’s use this MyMessage component by adding it to the render logic.

Start typing out the component:

<MyMessage

If your code editor supports code hinting, you will notice that the component’s signature will appear as you start to type out the component.

Screenshot of MyMessage's code signature.

This helpfully provides you with the expected values and types without having to navigate back to the component. This is especially useful when dealing with multiple components in separate files.

Examining Prop Types

Now, start typing out the props:

<MyMessage messa

As soon as you start typing message, you can see what that prop should be:

Screenshot of the expected message type.

This displays (JSX attribute) message: string.

Examining Type Errors

Try passing a numeric value for message instead of a string:

<MyMessage message={10} />

If we add a number as a message, TypeScript will throw an error and help you to catch these typing bugs.

Screenshot of TypeScript error that type number is not assignable to type string.

React won’t even compile if there are type errors like this:

Screenshot of compilation error when running the app in a web browser.

This displays Type 'number' is not assignable to type 'string'.

Conclusion

In this tutorial, you set up a React app with TypeScript using Create React App.

You can create types for all your components and props. You can benefit from code hinting with modern code editors. And you will be able to catch errors faster since TypeScript won’t even let the project compile with type errors.

If you’d like to learn more about TypeScript, check out our TypeScript topic page for exercises and programming projects.

Creative Commons License