How to Migrate your React Project to TypeScript
Tags: react, typescript
Published: 2022-11-29 15:02:54

---
title: How to Migrate your React Project to TypeScript
published: true
description: Today, we’re going to begin migrating my React project, Affirmation, to TypeScript.
tags: react, typescript
cover_image: https://a-us.storyblok.com/f/1001320/2400x1260/cfbd30716a/2211-how-to-migrate-your-react-project-to-ypescript-featured-1200x630-2x.png/m/
# Use a ratio of 100:42 for best results.
canonical_url: https://blog.deepgram.com/how-to-migrate-your-react-project-to-typescript/
---

As developers, one of the most important parts of the process is to ensure the reliability of the software that you’re creating. If you’re working with a team, it’s important to maintain readability, consistency, and dependability. One way to do this is to use TypeScript. Now if you’re like me, you might already have a project written with a frontend framework that doesn’t use TypeScript. Never fear, TypeScript allows you to incrementally migrate your project. Today, we’re going to begin migrating my React project, Affirmation, to TypeScript.

## 5 Reasons to Migrate to TypeScript
There are a lot of reasons–including the ones above–to migrate to TypeScript, but in case those didn’t convince you, here are five more:

- Decreases bugs in your code
- Improves onboarding of new contributors
- Decreases the need for tests
- Often makes projects easier to maintain
- Allows you to remove technical debt more quickly

## Getting Started
Since we’re building on an existing project, here are some resources to familiarize yourself with:

- [GitHub Repository](https://github.com/deepgram-devs/react-app)
- [How to Add Speech Recognition to Your React and Node.js project blog post](https://blog.deepgram.com/how-to-add-speech-recognition-to-your-react-project/)

The first thing we want to do is get the app running as is so we can ensure that as we upgrade, we won’t be making any breaking changes.

### Run the React Project
- [Clone the repository](https://github.com/deepgram-devs/react-app).
- Create a Deepgram API Key with an admin or owner role - get it [here](https://console.deepgram.com/signup?jump=keys).
- Create a file called .env and add DG_KEY='your-API-key' 
- Run `npm i` in your terminal.
- Run `npm run` start in your terminal.
- Run `node server/server.js` in your terminal.

If it doesn’t automatically open, navigate to http://localhost:3000/. You should see the project running.

## Adding TypeScript
In your terminal run `npm install --save typescript @types/node @types/react @types/react-dom @types/websocket`.

At the project root level, create a new file called [tsconfig.json] (https://www.typescriptlang.org/docs/handbook/tsconfig-json.html). The `tsconfig.json` file allows you to add specifications and compiler options for the project. You can either create the file yourself or run `npx tsc --init` in your terminal. With the second option, you’ll see that there are some active default options and a lot of options commented out that you can uncomment as needed.

Within our `tsconfig.json` you’ll see that we’re using `"strict": true`. When using this within the compilerOptions, TypeScript will validate as much as it can. This means there will be more checking, and more to update as you migrate your React project to TypeScript. But this also means you’ll get the most benefit from using TypeScript.

## Migrate React to TypeScript
Now that everything is up and running, we can start our migration. Because the main file we’re working with is `Affirmation.js`, we’re going to start there. Rename this file to `Affirmation.tsx` and then open the file.

We should immediately see three lines that need to be updated, lines 9 and 12 should have an indication that the `e` needs to be typed, and line 58 should also indicate that `socketRef.current` needs to be addressed.

If you’re working in VSCode, you can hover over each of these areas to get more details about the problem. Let’s take them one at a time.

If we hover over the `e` on line 9, we see this message:
![Parameter 'e' implicitly has an 'any' type](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qs5nw0n64ttmx946x2eu.png)
Now, we want to avoid having an `any` type. That doesn’t give us the protection that we want from TypeScript. So let’s take a look at the code to help us understand what this event is doing.
```js
const handleChange = (e) => {
		setAffirmation(e.target.value)
	}
```
This is in our `handleChange` function that’s attached to our `<textarea>` element. When our user types in the `<textarea>`, the event is passed to the `handleChange` function and becomes the value for our `setAffirmation` hook. We know that we don’t want the type of our event to be `any`. This is a journal app and that value is text, or more specifically, a string.

We need to let the application know that we don’t want it to accept any other type. We’re going to give our function a type of `React.ChangeEventHandler<HTMLTextAreaElement>` since we have access to `React.ChangeEventHandler` through `@types/react`. This is what it will look like if you use inline types:
```js
const handleChange: React.ChangeEventHandler<HTMLTextAreaElement> 
	= (e) => {
		setAffirmation(e.target.value)
	}
```
The next update we need to make is in our `handleSubmit` function:

```js
 const handleSubmit = (e) => {
		e.preventDefault()
		setFinalAffirmation(true)
	}
```
If we hover over the `e`, we get the same message we did above. You might be tempted to type it in the same way, but let’s think about what’s happening here for a second. We’re submitting a completed form here. If we head over to the [React TypeScript Cheatsheet](https://react-typescript-cheatsheet.netlify.app/docs/basic/getting-started/forms_and_events/#list-of-event-types), we’ll find an event type of `FormEvent`, which they describe as an “Event that occurs whenever a form or form element gets/loses focus, a form element value is changed or the form is submitted.” That sounds like a good choice.
```js
/* submit is a form event */
const handleSubmit = (e: 
   React.FormEvent<HTMLFormElement>) => {
		/* prevent page from refreshing */
		e.preventDefault()
		setFinalAffirmation(true)
	}
```
We add a comment there for clarity that submit is a form event, and then we specify the type as an `HTMLFormElement`.

We’ll move on to the last one in this example.

Around line 57, we can see that TypeScript is complaining about `socketRef.current`. If we hover over it, we get this message:
![Type 'WebSocket' is not assignable to type 'null'](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uu1y0hn4dvb0xo76tlim.png)

Because we added the WebSocket types package, `@types/websocket`, we have access to a WebSocket type. However, we don’t set the type on line 57. The actual problem is with `const socketRef = useRef(null)`.

We need to let TypeScript know that we’re looking at a WebSocket or null: `const socketRef = useRef<WebSocket | null>(null)`.

With that last update, we no longer have TypeScript complaining in this file. That doesn’t mean that there aren’t other updates that we can make. If you hover over other variables or functions, we can see what TypeScript is inferring.

![gif hovering over code](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ny009v1ukv7hxfz820uo.gif)

To complete this migration, we need to update the .js files to .tsx. But the nice thing is that we don’t have to do that all at once. For now, this is where we’ll leave it.

## Learn More About TypeScript
There’s a lot to learn about TypeScript. Here are some resources I've found helpful:

- [TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
- [Totally TypeScript](https://www.totaltypescript.com/tutorials/beginners-typescript)
- [React + TypeScript Cheatsheets](https://github.com/typescript-cheatsheets/react#reacttypescript-cheatsheets)

And check out the Bonus Section of Sandra’s post on how to [Build a To-do List App with Pinia and Vue 3](https://blog.deepgram.com/build-a-todo-list-with-pinia-and-vue-3/#bonus-section:-add-typescript).

To access the code for this blog post, select the `feature/typescript` branch from the [React App GitHub Repository](https://github.com/deepgram-devs/react-app). If you have any thoughts, comments, or questions, please drop a comment in our [General Discussion category](https://github.com/orgs/deepgram/discussions/categories/general), or if you want to say hey, drop your intro in our [intro thread](https://github.com/orgs/deepgram/discussions/3).