DEV Community

Omer Elbaz
Omer Elbaz

Posted on

TypeScript - The Best Way to Use It with React

Why TypeScript?

I have another article that explains a lot about TypeScript, what it is and how and why you should use it.
You're welcome to read about it here: https://dev.to/omerwow/how-i-began-using-typescript-3noe

In a nutshell, the benefits of using TypeScript include:

  1. Catching errors early in the development process.
  2. Making code easier to understand and maintain.
  3. Providing a better development experience, with features like autocompletion and type checking.

Getting started

To create a new React application with TypeScript, use the following command:

npx create-react-app my-app --template typescript
Enter fullscreen mode Exit fullscreen mode

That's it, the Create React App CLI will create a new app with TypeScript configured properly and you can get started right away.

If, however, you have an existing React app that you want to convert to TypeScript, you're going to need to do a few extra steps.
Don't worry though, it's pretty simple!

First, install TypeScript and other required packages:

npm install --save typescript @types/node @types/react @types/react-dom @types/jest
Enter fullscreen mode Exit fullscreen mode

Now, rename all .js files to .tsx files, and make sure to restart your dev server before continuing.
Also, a restart to your code editor / IDE may be needed or helpful as well.

The last thing you're going to need to do is to create a tsconfig.json file.
This file will usually be created for you when creating a new project, but since this an existing project, you're going to need to create it yourself.

In the root folder of your project, just create a new file called tsconfig.json, and paste the following inside it:

{
  "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"
  ]
}
Enter fullscreen mode Exit fullscreen mode

That's pretty much it.
Be aware that enabling TypeScript in an existing project can "introduce" or uncover some errors.
This is usually not a big deal and may even be pretty helpful and help you solve a few bugs. You're going to need to deal with them before continuing development.

Now that we have a working TypeScript React app, we can start utilizing TypeScript to improve our development.

Writing .tsx files

We'll start with a simple React component that renders a header. Then we'll use TypeScript to add types and type safety to the component. Finally, we'll compile the TypeScript code to JavaScript and run the app.
First, let's create a simple React component that renders a header:

import React from 'react';

const Header = () => {
  return (
    <header>
      <h1>Hello, world!</h1>
    </header>
  );
};

export default Header;
Enter fullscreen mode Exit fullscreen mode

This Header component doesn't do much yet it just renders a header element with the text "Hello, world!" We can write this component in TypeScript or JavaScript. For this example, we'll write it in TypeScript.

Adding Types with TypeScript

Now that we have a basic React component, let's add some types with TypeScript. We can start by adding types to our props and state:

import React from 'react';

interface HeaderProps {
  message: string;
}

const Header = (props: HeaderProps) => {
  return (
    <header>
      <h1>{props.message}</h1>
    </header>
  );
};

export default Header;
Enter fullscreen mode Exit fullscreen mode

As you can see, we've added an interface for our props and specified that the message prop is of type string. This way, if we try to pass anything other than a string to the message prop, TypeScript will give us an error.

We can also add types to our state:

import React, { useState } from 'react';

const [count, setCount] = useState<number>(0);

const Header = (props: HeaderProps) => {
  return (
    <header>
      <h1>{props.message}</h1>
      <button onClick={() => setCount(count + 1)}>
        Click me!
      </button>
      <p>You've clicked the button {count} times.</p> 
    </header>
  );
};

export default Header; 
Enter fullscreen mode Exit fullscreen mode

As you can see, we've added types for our state and specified that the count state variable is of type number. This way, if we try to set the count state variable to anything other than a number, TypeScript will give us an error.

Exploring the type safety of React event handlers

One of the benefits of using TypeScript with React is that developers can catch errors in their event handlers. Event handlers are a way to respond to user input in React applications. When an event occurs, such as a user clicking a button, The compiler will check the type of each parameter in the event handler function, and it will also check the return type of the function. If there is a mismatch in either of them, the compiler will throw an error. This means that developers can catch errors in their event handlers before the code runs.

However, there are some potential pitfalls when using TypeScript with React. One pitfall is that it is possible to write code that is valid TypeScript but will not compile because of an error in React. For example, take a look at the following code:

class MyComponent extends React.Component {
  handleClick(event: MouseEvent) {
    // do something
  }
}
Enter fullscreen mode Exit fullscreen mode

This code will not compile because of an error in React: "handleClick" must be declared as a static method on "MyComponent". However, this code is valid TypeScript, and it will only produce an error when it is compiled with React. This means that developers need to be aware of both TypeScript and React when they are writing their code.

In conclusion, TypeScript is a great way to improve your React code. It can help you catch errors, optimize performance, and make your code more readable. Plus, it's just plain fun to use.

Star our Github repo and join the discussion in our Discord channel!
Test your API for free now at BLST!

Discussion (17)

Collapse
yongchanghe profile image
Yongchang He

Thank you for sharing this!

Collapse
behrjozef profile image
Jozef Behr

Thank You man for sharing this , just trying to learn.

Collapse
brense profile image
Rense Bakker

You have to add a tsconfig file to your existing project aswell

Collapse
omerwow profile image
Omer Elbaz Author

This is from the official Create React App docs:

You are not required to make a tsconfig.json file, one will be made for you. You are allowed to edit the generated TypeScript configuration.

Collapse
joelbonetr profile image
JoelBonetR • Edited on

@brense pointed out "to your existing project" and he's right, if you want to add TS to a pre-existing project without TS, you'll need to create it.

By the way, Create React App installer is an oppinionated bunch of dependencies unraveled together from a single command, it's meant for learning purposes and not for serious projects in which you need to analyse which dependencies you do really need.
So most of the time IRL yes, you'll need to write the tsconfig file.

Thread Thread
omerwow profile image
Omer Elbaz Author

You're right, I added this to the article, thanks.

Also, this article is meant for beginners that want to get started and experiment with TypeScript and React, it does not claim to have anything production ready :)

Thread Thread
joelbonetr profile image
JoelBonetR

It's worth mentioning though.
In tones of companies they ask explicitly to "create a react app without using create-react-app executable" in the tech interview process, and for good reasons;
Being able to tweak the initial setup means (to a certain point) that you understand the needs of the acceptance criteria (so don't overengineer) as well as the basics to maintain those pieces of software up to date and aligned to the project needs as well.

If you didn't yet, try to set up a React application with Parcel bundler instead webpack, maybe use mocha and/or other stuff for testing and so on. Do it step by step and full-forward.
If you use create-ract-app and then start deleting dependencies and adding new ones you'll probably end up with a mess and loosing a good amount of time and the knowledge gathered from that experience will be negligible.

Instead, add the dependencies one by one when they make sense and don't hesitate to use npm audit to check if there's any known bug or weakness on any used package as good practice.

Best regards.

Thread Thread
brense profile image
Rense Bakker

Yea I've moved away from webpack, I'm using vite now to build my React apps.

Thread Thread
brense profile image
Rense Bakker

CRA also comes with a nice collection of critical vulnerabilities (inside webpack dependencies) that havent really been fixed for almost half a year now...

Thread Thread
joelbonetr profile image
JoelBonetR

Never tried Vite yet. For personal projects I always use Parcel for the "ease of use", rollup didn't catch it much and Webpack makes me feel like it's a whole new thing each version 😅

BTW I'm using Next JS for both sideprojects and work since a year ago and it comes with webpack so... Here we are. Glad I don't need to edit it, it works with the next.config instead 😂

Thread Thread
brense profile image
Rense Bakker

Yea webpack is ok if you dont have to touch it lol. It's really slow though... I think there's a Next JS alternative that uses vite... dev.to/cyco130/rakkas-nextjs-alter...

Collapse
brense profile image
Rense Bakker

If you use CRA yes, but if you add typescript to an existing React project, you need to add your own tsconfig.

Collapse
andrewbaisden profile image
Andrew Baisden

TypeScript is the natural progression for JavaScript developers.

Oh and just a heads up that you can add highlighting to the code blocks if you'd like. Just change:

code block with no colors example

... to specify the language:

code block with colors example

More details in our editor guide!

Collapse
madza profile image
Madza

this was a great read

Collapse
ash_bergs profile image
Ash

Fantastic write up! I've really been coming around to TypeScript lately... but it definitely took a little time 😅

Collapse
mdmarufsarker profile image
Md. Maruf Sarker

Great article 👌

Collapse
vishalraj82 profile image
Vishal Raj

Great. Here is my guide to getting started with React and TypeScript - dev.to/vishalraj82/getting-started...