Update 2/9: The types have been updated for the inclusion of hooks making SFC no longer a valid definition. If you notice any other issues, please comment.

This tutorial will show you how to quickly get started building React applications using TypeScript without needing any configuration by using create-react-app (CRA). We will assume that you already have Node and NPM installed on your machine. Your TypeScript/React app will work right out of the box without needing to eject CRA. In addition, you will learn how to build your own components and manage props and state using TypeScript.

You can also find the entire source code on GitHub.

Install create-react-app

create-react-app is a command line tool that allows developers to easily create new React apps with sensible defaults and zero configuration.

npm install -g create-react-app

Note: This step is now optional. TypeScript can be installed using npx which will be shown in the following section.

Initialize your React app with TypeScript

Invoke the create-react-app command with an additional TypeScript option to generate a React application using TypeScript as the default JS syntax.

npx create-react-app my-app --typescript

npx is a command released with npm 5.2 which allows you to execute CLI commands and executables hosted by the registry — meaning global installations are no longer required.

If you have used create-react-app before, this should look very familiar. The additional piece of information is adding the --typescript flag. This flag tells CRA to use TypeScript as the default syntax and add the appropriate configuration to make it work out of the box.

This will generate the following files and folder structure:

my-app/

├─ .gitignore

├─ node_modules/

├─ public/

├─ src/

| — — index.tsx

| — — registerServiceWorker.ts

| — — logo.svg

| — — App.tsx

| — — App.test.tsx

| — — App.css

| — — index.css

| — — assets/

├─ package.json

├─ tsconfig.json

├─ tsconfig.test.json

└─ tslint.json

The following is an explanation of each part:

tsconfig.json declares the TypeScript options. It sits at the root of a TypeScript project and indicates the compiler settings and files to include.

declares the TypeScript options. It sits at the root of a TypeScript project and indicates the compiler settings and files to include. tslint.json is the linter settings to be used by TSLint.

is the linter settings to be used by TSLint. public is the folder of static assets that will be served such as the HTML document and manifest file.

is the folder of static assets that will be served such as the HTML document and manifest file. src holds the app UI code. This includes our TypeScript components and CSS styling. The traditional index.js file has been replaced by index.tsx as the entry point.

React types for TypeScript with declaration files

In addition to configuring the TypeScript compilation, we also receive all the declaration files needed to use TypeScript with React. A declaration file is used to describe the types of files written in native JavaScript — it can be viewed as an interface between JavaScript and TypeScript. These files are prefixed with the @types declaration. The create-react-app TypeScript configuration ships with the following declaration files.

@types/jest

@types/node

@types/react

@types/react-dom

These are installed via NPM and can be found in your package.json folder.

React modifications for TypeScript

To use React with TypeScript, you must make some minor modifications to how you build a standard React app.

Use .tsx files for JSX

In addition to a new .ts file for TypeScript, there is also a new file extension .tsx . This is the extension that you should use anytime you include the JSX syntax in a React component file. You also need the jsx set to true which is done by default. TypeScript is able to compile JSX directly into JavaScript. For more information, you can review the TypeScript docs on JSX.

Importing React and ReactDOM

You may notice that in the default components use the following syntax:

import * as React from 'react';

import * as ReactDOM from 'react-dom';

You can no longer import React from 'react'; . React is exported as a CommonJS module which does not use a default export. At this point, it’s not imperative to know exactly why, but to just be aware of how you should import React to make it work. This also means that you declare you components as class App extends React.Component {...} .

Creating and maintaining a resume isn’t fun. Instead, let us generate an awesome resume for you :) Resume Builder >

Building components

One of the best parts about using TypeScript is that you no longer need to use the prop-types package. There is a slight learning curve to using TypeScript for props and state, but once you understand it, it’s much more powerful than the React default methodology.

You will define a props interface for each of you components that you pass props to. This declares the shape of the object and the types associated with the keys. In addition, you must declare an interface for the state of class components.

Function Component

To demonstrate a functional component with props, we will replace the <h1> header in App.tsx with our own <Header/> component. Start by creating ./src/Header.tsx . It receives a prop name that will say hello to the person’s name. Inside our file, we will create a functional component:

We start by importing React. Then we declare the interface IProps with a single string prop of name? . We will make the name optional, so we indicate that with a ? . Marking a key as optional means that its type can be either string | undefined .

When we create the Header component, notice the React.FC<Props> . The “FC” stands for function component (shorthand for the React.FunctionComponent interface). While this declaration is not required, it is what allows us to use defaultProps and children . Finally, we declare the props type as IProps referencing the interface that we created.

NOTE: In previous versions of React we used SFC , which stood for “stateless functional component” which is no longer true with the introduction of React Hooks in v16.8.

Class component

To show the fundamentals of a class component, we will replace the <p> description in App.tsx with a counter. One of the key differences between a class and functional component is that a class component can maintain its own state. The other primary difference is the ability to access lifecycle methods which is outside the scope of this tutorial.

Create a ./src/Description.tsx file and add the following code.

We begin by declaring an interface for both the IProps and IState . There will be an optional prop call countBy which will determine the increment value. The component itself will maintain the count using its state.

The component is declared with the types IProps and IState as

class Description extends React.Component<IProps, IState> { and the defaultProps are declared as a static variable. The state is initialized with a count of 0.

The increase function is used to increment the counter. The countBy is extracted as const countBy: number = this.props.countBy!; . The exclamation mark ! indicates to TypeScript that we know the value will exist and to not throw a potential undefined error. Finally we create the HTML to wire up the component.

Your final create-react-app with TypeScript components

Inside our App.tsx we import the components we just created and replace the default HTML from CRA. The name prop and countBy prop must match the types declared in the child component. Since the props are both optional, they can also be undefined, and defaultProps will be used.

And that’s all you need to get started with TypeScript and React! Your application should now have the new features and be fully running with TypeScript. Run the following to see your application working:

yarn start

If you’re interested in React and TypeScript follow the gitconnected publication for more of our upcoming tutorials. We will show you how to build production-quality React application using TypeScript.