Getting Started with React and TypeScript
Tags: reacttypescriptwebde
Published: 2021-01-28 19:34:43

---
title: Getting Started with React and TypeScript
published: true
date: 2021-01-27 17:00:56 UTC
tags: reacttypescriptwebde
canonical_url: https://www.thisdot.co/blog/getting-started-with-react-and-typescript
---

# Getting Started with React and TypeScript

React and TypeScript makes for a fantastic combination when it comes to developing web sites and web applications. With React's focus on creating a fantastic user interface and TypeScript's ability to type check our code, it's never been easier to sanely develop a fantastic user experience.

## Prerequisites

Before getting started, you'll need NodeJS and NPM installed. Go [here](https://nodejs.org/en/download/) to find instructions on how to install it on your computer.

You should also have a bit of knowledge in using React. If not, I highly recommend getting started learning React using vanilla JavaScript.

## Create React App

Facebook's Create-React-App is a preview of the wonderful development experience React has to offer. It will enable us to start writing code _immediately_.

Check out their documentation [here](https://create-react-app.dev/) if you have any questions or want to dive in a touch deeper on how the tool works.

In summary, Create-React-App will set up a complete development environment for us. It will configure and conceal build tool configurations for us so that all we need to focus on is our code. Here is some of the tooling that CRA (create-react-app) sets up for us:

- [Babel](https://babeljs.io/)
- [Webpack](https://webpack.js.org/)
- [ESLint](https://eslint.org/)
- [TypeScript](https://www.typescriptlang.org/)

Let's use this tool now to create our TypeScript/React development environment. Use the following command to generate a new Typescript React App.

```
npx create-react-app my-app --template typescript
```

If you use yarn, use the following command:

```
yarn create react-app my-app --template typescript
```

After the tool has finished running, switch directories into `my-app` run the command `npm start` to spin up your development environment. Once it's done loading, we should see localhost:3000 open up.

[![Create React App Home Page](https://images.ctfassets.net/zojzzdop0fzx/3yt8fqPF4a0w0mSaFBPTES/1c1b6d0418314ccc6bc5b4ee3363c520/react-app-index.png)](https://images.ctfassets.net/zojzzdop0fzx/3yt8fqPF4a0w0mSaFBPTES/1c1b6d0418314ccc6bc5b4ee3363c520/react-app-index.png)

## Folder Structure

Create-react-app scaffolds out the [folder structure](https://create-react-app.dev/docs/folder-structure) of your app for us, minimizing the amount of code you need to write to go from idea to production.

Here are some important files to take note of:

- `public/index.html` - This is the HTML file that consumes the bundle generated by Create-React-App's hidden tooling.
- 

`src/index.tsx` - This is the TypeScript entry point file. All of the project's dependencies are mapped out by Webpack (all set up for us invisibly by CRA) using this file. The bundle generated is injected into `public/index.html`. This file has a few responsibilities. The most important are:

  - `import` our main React component
  - Render that App component to the DOM using `ReactDom.render()`
- `src/App.tsx` - This is our main React Component. The `.tsx` extension tells us that the file uses both TypeScript and JSX. This is the main component in our app which is rendered to the DOM by ReactDOM. We'll spend most of our time in this file getting the hang of writing React code using TypeScript.
- `tsconfig.json` - This is the TypeScript configuration file. This file was generated for us by Create-React-App and we can freely edit this configuration to best suit our needs.

## Hello, World - With TypeScript and React

Let's get to coding.

To keep things organized, make a new folder `src/components` and create our new component, `src/components/HelloWorld.tsx`. In this file, we'll write just 2 lines of code:

```
const HelloWorld = () => <h1>Hello, World!</h1>
export default HelloWorld
```

The first line defines our new component. It's simply a function that returns some JSX. In this case, it's our "Hello, World!" heading tag. The second line exports the component, allowing other modules to import it.

To import and use this component, load up `src/App.tsx` and do the following:

- Include `import HelloWorld from './components/HelloWorld'` at the very top of the file to import the component
- Use the component by having the App component return some JSX which includes `<HelloWorld />`.

After some refactoring, your `App.tsx` might look something like this:

```
import './App.css';
import HelloWorld from './components/HelloWorld'

const App = () => {
  return (
    <div className="App">
      <HelloWorld />
    </div>
  );
}

export default App;
```

In the above example, I've left the default styles, imported our HelloWorld component, and refactored the JSX which is returned by `App` so it includes `<HelloWorld />`.

[![Hello World in React](https://images.ctfassets.net/zojzzdop0fzx/2SxznBAAQ3b8hY2gogjU1j/6c2cc0955b0290e3e2b51dd28a700d88/hello-world.png)](https://images.ctfassets.net/zojzzdop0fzx/2SxznBAAQ3b8hY2gogjU1j/6c2cc0955b0290e3e2b51dd28a700d88/hello-world.png)

### Adding a bit of TypeScript

Let's increase the safety of our code by using some TypeScript features.

This is what our `src/components/HelloWorld.tsx` looks like right now:

```
const HelloWorld = () => <h1>Hello, World!</h1>
export default HelloWorld
```

A huge benefit of TypeScript is that it can help us catch errors before you run your code instead of at run-time. Let's introduce a bug to our code:

Refactor our HelloWorld component so it looks like this:

```
const HelloWorld = () => "Hello, World!"
export default HelloWorld
```

This is valid JavaScript, but not valid React. A functional component must return JSX (or null). It can't just return a string. We're made aware of this error when Create-React-App tries to build our code.

[![JS-error](https://images.ctfassets.net/zojzzdop0fzx/6kO4Ku07QzRteaUcmtX2yd/5f61c30eb6f1fc28f6824c639262c157/JS-error.png)](https://images.ctfassets.net/zojzzdop0fzx/6kO4Ku07QzRteaUcmtX2yd/5f61c30eb6f1fc28f6824c639262c157/JS-error.png)

Let's refactor our code to use some TypeScript features so our editor notices the error:

```
import { FC } from 'react'
const HelloWorld: FC = () => "Hello, World!"
export default HelloWorld
```

The `import` statement imports the FunctionComponent type `FC`, and allows us to type our functional component to ensure it returns valid JSX. By typing the function, our editor can now immediately show us our error. Click [here](https://www.typescriptlang.org/docs/handbook/functions.html) for more information on typing functions in TypeScript.

[![Throwing our first typescript error](https://images.ctfassets.net/zojzzdop0fzx/2pHtsme5tHxjAVF4usAT7B/8817a8ab9592b081bab665ef6525a9d8/typescript-error.png)](https://images.ctfassets.net/zojzzdop0fzx/2pHtsme5tHxjAVF4usAT7B/8817a8ab9592b081bab665ef6525a9d8/typescript-error.png)

TypeScript is explicitly telling us that we can't assign a return type of `string` to our functional component. Now that TypeScript has shown us this error, let's correct it.

```
import { FC } from 'react'
const HelloWorld: FC = () => <h1>Hello, World!</h1>
export default HelloWorld
```

By fixing our function and returning JSX, `HelloWorld` now passes TypeScript's type checks and no error is thrown. As a result, our project builds and works once more.

## Benefits of TypeScript

As shown in the previous example, TypeScript can help us catch errors before we even leave our code editor. This results in faster development since TypeScript will be actively debugging your code _as you write_. Better to catch silly errors immediately than insanity-inducing errors during run-time.

Let's show another example of how enforcing types can help us catch errors early.

We'll create a new React component, `List`. This new component will take an array of string data as a prop and return some JSX which renders a `<ul>` tag and iterate over the list of data, rendering an `<li>` for each piece of data.

Here is what my version of this component could look like with more type safety from TypeScript included.

`src/components/List.tsx`

```
import { FC } from 'react'

const List: FC<{ data: string[] }> = ({ data }) => (
  <ul>
    {data.map(item => <li>{item}</li>)}
  </ul>
)

export default List
```

Just like our previous example, we import `FC` from `react` and use it to type our function. What we're _also_ doing is defining a type for our `data` prop. In this example, we are saying that `data` is an [array](https://www.typescriptlang.org/docs/handbook/basic-types.html#array) of strings. Notice how self-documenting that is. This is a huge benefit of TypeScript.

Now let's insert this component into `src/App.tsx`, pass into it an array of data, and sprinkle in a bit more TypeScript.

`src/App.tsx`

```
import './App.css';
import { FC } from 'react'
import HelloWorld from './components/HelloWorld'
import List from './components/List'

const avengers = [
  'Captain America',
  'Iron Man',
  'Black Widow',
  'Thor',
  'Hawkeye',
]

const App: FC = () => {
  return (
    <div className="App">
      <HelloWorld />
      <List data={avengers} />
    </div>
  );
}

export default App;
```

We created an `avengers` array, with 5 members of the Avengers team. We then passed in this list of data as a property to `List`. This example works because we defined `List` to accept an array of strings. Let's trigger a TypeScript error and send it a more varied array.

```
import './App.css';
import { FC } from 'react'
import HelloWorld from './components/HelloWorld'
import List from './components/List'

const avengers = [
  'Captain America',
  'Iron Man',
  'Black Widow',
  'Thor',
  'Hawkeye',
  {
    name: 'Vision',
  },
  {
    name: 'Hulk',
    color: 'green',
  },
]

const App: FC = () => {
  return (
    <div className="App">
      <HelloWorld />
      <List data={avengers} />
    </div>
  );
}

export default App;
```

We added 2 new heroes to the `avengers` array, Vision and the Hulk, but we added them as objects, not as strings. This causes TypeScript to throw an error.

[![Another TypeScript Error](https://images.ctfassets.net/zojzzdop0fzx/2ecwMdoHqpzPWsykQN8Bcg/050014340ffda9f0a0ac2b7f03e3add4/typescript-error-2.png)](https://images.ctfassets.net/zojzzdop0fzx/2ecwMdoHqpzPWsykQN8Bcg/050014340ffda9f0a0ac2b7f03e3add4/typescript-error-2.png)

TypeScript is telling us that our data doesn't fit the definition of the `data` prop. It even points out to us exactly where this prop is defined. Let's assume that we should be sending an array of objects instead of strings. Let's refactor our files so everything works again.

`src/App.tsx`

```
import './App.css';
import { FC } from 'react'
import HelloWorld from './components/HelloWorld'
import List from './components/List'

const avengers = [
  { name: 'Captain America' },
  { name: 'Iron Man' },
  { name: 'Black Widow' },
  { name: 'Thor' },
  { name: 'Hawkeye' },
  { name: 'Vision' },
  { name: 'Hulk' },
]

const App: FC = () => {
  return (
    <div className="App">
      <HelloWorld />
      <List data={avengers} />
    </div>
  );
}

export default App;
```

`src/components/List.tsx`

```
import { FC } from 'react'

const List: FC<{ data: { name: string }[] }> = ({ data }) => (
  <ul>
    {data.map(({ name }) => <li>{name}</li>)}
  </ul>
)

export default List
```

We changed our `List` component definition and explicitly typed the data prop to be an array of objects containing a string type name property. By explicitly typing our `data` prop, we know its exact shape and can catch if we send this component any prop that is shaped differently than this.

[![Avengers UI](https://images.ctfassets.net/zojzzdop0fzx/1aLDoY4TLR89ZJgJ6SJ6W4/136efaffce02376e21e19a25a3e0c088/avengers-ui.png)](https://images.ctfassets.net/zojzzdop0fzx/1aLDoY4TLR89ZJgJ6SJ6W4/136efaffce02376e21e19a25a3e0c088/avengers-ui.png)

## Conclusion

By adding a type layer over JavaScript, TypeScript successfully saves developers time and frustration, even giving us a hand in self-documenting our code. While there surely is much more left to learn in typing your React applications, this should be a good platform to begin wading into the deep end of the pool, so to speak.

Happy coding!

_This Dot Labs is a modern web consultancy focused on helping companies realize their digital transformation efforts. For expert architectural guidance, training, or consulting in React, Angular, Vue, Web Components, GraphQL, Node, Bazel, or Polymer, visit [thisdotlabs.com](https://www.thisdotlabs.com)._

_This Dot Media is focused on creating an inclusive and educational web for all. We keep you up to date with advancements in the modern web through events, podcasts, and free content. To learn, visit [thisdot.co](https://www.thisdot.co)._