Tuesday, 30 October, 2018 UTC


Summary

Now that Create React App v2 is out, official TypeScript support comes with it. This is an exciting thing for JavaScript users that use TypeScript. TypeScript is a powerful tool that helps us write safer and self-documenting code. We can catch bugs faster with TypeScript.
Related Reading: From JavaScript to TypeScript: Types & Variables
Many people have opinions about TypeScript, good and bad, but it's a good idea to give it a chance. Ken Wheeler did and we have this tweet now:
For this article, we'll focus on getting a Create React App up with TypeScript and we'll do a larger project where we use TypeScript and React together in a future article.
Starting a TypeScript Create React App
This is the easiest part!
npx create-react-app my-typescript-app --typescript
What packages does the --typescript flag get us and what changes does it make?

The TypeScript Additions

The --typescript flag will add the main TypeScript package.
We also get this notice: We detected TypeScript in your project (src/App.test.tsx) and created a tsconfig.json file for you.
The tsconfig.json file is how we configure TypeScript projects similar to how package.json is for JS projects.

tsconfig.json

The default tsconfig.json doesn't really have much we should concern ourselves with when getting started.
{
  "compilerOptions": {
    "target": "es5",
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve"
  },
  "include": ["src"]
}
The App.tsx File
Let's jump into the main App file that usually is our main React component. You may be worried that this file is a scary looking file full of TypeScript typings. Let's look:

App.tsx

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    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;
Wait a minute!
It's the same as the JavaScript App.js!
We get the same base as our JavaScript projects, but we can sprinkle TypeScript on top. Let's create a TypeScript component and see what benefits we can gain.
Creating a TypeScript Component
We'll start by creating a normal functional component in this same App.tsx file:

A JavaScript Component

function MyMessage({ message }) {
  return <div>i shall speak! my message is: {message}</div>;
}
A simple component where we pull message out of props. Now let's add some TypeScript to tell this function that it's message parameter should be a string:

Adding TypeScript

If you're familiar with TypeScript, you may think you want to add the following to message: message: string. What we have to do in this situation is define the types for all props as an object. There's a few ways we can do this:

Types Inline

function MyMessage({ message }: { message: string }) {
  return <div>i shall speak! my message is: {message}</div>;
}

Props Object

function MyMessage(props: { message: string }) {
  return <div>i shall speak! my message is: {props.message}</div>;
}

Separate Types Object

interface MyMessageProps {
  message: string;
}

function MyMessage({ message }: MyMessageProps) {
  return <div>i shall speak! my message is: {props.message}</div>;
}
There are many ways to use TypeScript in our projects. 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 for writing a bit more.
We've told this component that it only accept 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.
My favorite part about TypeScript is that it let's us write self-documenting code.
When we go to use this component, we can see VS Code bring up the component's signature right as we type! We don't have to jump back to the component (especially if it's in another file) to see what its inputs should be.
Now that isn't the most readable, so let's jump into using each prop individually.

Seeing Prop Types

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

Seeing Type Errors

If we add a number as message, TypeScript will throw an error and help us catch these typing bugs.
React won't even compile if there are type errors like this:
Conclusion
This only scratches the surface of what TypeScript provides us. You can create types for all your components and props and with VS Code, be able to read those easily. You'll also catch errors faster since TypeScript won't even let the project compile with type errors.