Ogundipe Samuel Software engineer and technical writer.

Using TypeScript with React: A tutorial

6 min read 1868

Using TypeScript With React: A Complete Tutorial

In this React and TypeScript tutorial, we’ll tell you everything you need to know about using TypeScript in React, including reasons why you should use TypeScript in React, how to install and configure the open-source language, and how to use TypeScript interfaces with React components.

We’ll cover the following in detail:

What is TypeScript?

TypeScript is a free, open-source programming language developed and maintained by Microsoft. It is a strict superset of JavaScript that adds optional static typing and class-based object-oriented programming to the language.

What is React?

React was originally created by Facebook and has become one of the most popular libraries in the frontend world today. React is easily extendable and can include features like routing as well as state management patterns with libraries like Redux. React is minimal in its footprint but can be customized for almost any project. For more about React on a high level, check out the official React documentation.

Is TypeScript good for React?

TypeScript can be helpful to React developers in a number of ways. Below are just a few benefits of using TypeScript in React.

  • Interfaces: TypeScript allows you to define complex type definitions in the form of interfaces. This is helpful when you have a complex type that you want to use in your application, such as an object which contains other properties. This results in strict checks which in turn reduces the amount of possible bugs you might have produced without it.
  • IDEs: TypeScript is very helpful while using IDEs like Visual Studio, Visual Studio Code, Atom, Webstorm, Eclipse, and so many more as they provide better autocomplete and snippet generation, which makes development faster.
  • Readable, easily understandable code: The key to TypeScript is that it’s a statically typed script. Programming languages can either be statically or dynamically typed; the difference is when type checking occurs. Static languages’ variables are type-checked, which helps make the code more readable.

Installing and configuring TypeScript

To install TypeScript globally so you can call it when needed, run:

npm install -g typescript

For verification of the installed TypeScript, use the tsc — v command:

tsc --v //Version 2.6.1

Now, create a folder that will hold the application. To do this, run npm init and follow the instructions:

//create a new directory
mkdir typescript-react
//change directory to the new folder
cd typescript-react
//run npm init
npm init

Given no arguments, tsc will first check tsconfig.json for instructions. When it finds the config, it uses those settings to build the project.

Does TypeScript compile React code?

Create a new file called tsconfig.json in the root folder and add:

We made a custom demo for .
No really. Click here to check it out.

  "compilerOptions": {
    "target": "es6",
    "jsx": "react",
    "module": "commonjs"
  "exclude": [

This defines the two major sections, which include compilerOptions and exclude parameters:

  • In the compiler options, a target of es6 has been set. This means that the JavaScript engine target will be set to es6, and the module will be set to CommonJS. Notice that there is also a key called JSX, which is set to React. This tells TypeScript to compile JSX files as React files. This is similar to running tsc — jsx react.
  • In the exclude block, node_modules is being defined for it. TypeScript will not scan the node_modules folder for any TypeScript file while compiling
  • If you’re familiar with TypeScript and its configuration, you must wonder why the include section is missing. This is because webpack will be configured to handle taking in the entry file, passing them to TypeScript for compilation and returning a bundled executable for browsers

Configuring webpack

First, you need to install webpack and a webpack plugin called ts-loader. To do this, run:

npm install webpack ts-loader

Now you may wonder what ts-loader is. As its name implies, ts-loader is the TypeScript loader for webpack. You wouldn’t be wrong to say it’s a plugin that helps webpack work well with TypeScript.

Just like TypeScript, webpack also checks for a file called webpack.config.js for configuration. So create a new file called webpack.config.js and add:

var path = require("path");
var config = {
  entry: ["./app.tsx"],
  output: {
    path: path.resolve(__dirname, "build"),
    filename: "bundle.js"
  resolve: {
    extensions: [".ts", ".tsx", ".js"]

  module: {
    loaders: [
        test: /.tsx?$/,
        loader: "ts-loader",
        exclude: /node_modules/

module.exports = config;

The code base above is simple. Let me explain.

The first key, entry, refers to the entry point of the application. The app.tsx file referenced here is yet to be created. You will create it soon, hold on.

The output key is an object that accepts two parameters: the first is the path to publish bundled files, while the second is the name of your final bundle.

The resolve key is also an object that takes in a key called extensions with an array of extensions it should watch out for and compile.

The module key, which is the last key to discuss, is an object that has a key called loaders. The loaders key is an array of objects that defines which webpack plugin/loader should handle such file.

Here, we test for tsx extensions and ask webpack to use the ts-loader earlier installed the compilation.

Adding npm scripts

After all configured so far, wouldn’t it make sense if you could just run a command like npm run magic anytime you want to create a bundle? Yes, it would. So, open your package.json file and update your scripts section with:

"scripts": {
   "magic": "webpack"

Creating the app.tsx file

Typically, that’s most of the configuration needed. There’s just one more rule to follow all the configuration you have done above: install types definitions for every library you install.

For example, you install react this way:

npm install react @types/react

Install both react and react-dom to start with:

npm install react react-dom @types/react @types/react-dom

Next, create a new file called app.tsx in the root and add:

import * as React from "react";
import * as ReactDOM from "react-dom";
<h1>Hello, Welcome to the first page</h1>

Above is a simple React setup, except that it is using TypeScript. Move ahead to compile the file by running npm run magic in your terminal. A build folder with a file named bundle.js has been created.

Does this newly created bundle work as expected? Create a new index.html file that references the new build to find out:

<!DOCTYPE html>
    <meta charset="utf-8">
    <title>Getting Started with Typescript and ReactJS</title>
    <!-- this is where react renders into -->
    <div id="root"></div>

    <script src="build/bundle.js"></script>

If you double-click on the index.html file to open in a browser, you will see:

Creating a React component in TypeScript

You know you’ve got the basics of writing React in TypeScript when you have your first page ready. Now it’s time to dive into writing React components.

First, create a new folder called src, which is where components will live. Next, create a file called FirstComponent.tsx and paste:

import * as React from "react";

let Logo ="https://logrocket.com/img/logo.png";

export default class FirstComponent extends React.Component <{}> {
        render() {
                return (
                                {/* React components must have a wrapper node/element */}
                                <h1>A Simple React Component Example with Typescript</h1>
                                        <img src={Logo} /> 
                        <p>I am a compinent which shows the logrocket logo. For more info on Logrocket, please visit Https://logrocket.com</p>

The above code block is a simple component that returns a logo and some text. To make this new component accessible to React, you need to import and use the component in the base app.tsx file. Alter your app.tsx file to:

import * as React from "react";
import * as ReactDOM from "react-dom";
import FirstComponent from './src/FirstComponent'
<h1>Hello, Welcome to the first page</h1>

Looking at the code block above, you see that the differences are on line 3 and 7, where you imported the new component and rendered it, respectively.

If you run the npm run magic command and navigate to your browser, you will see:

Using TypeScript interfaces with React components

One of TypeScript’s core principles is that type checking focuses on the shape that values have. This is sometimes called “duck typing” or “structural subtyping.”

In TypeScript, interfaces fill the role of naming these types and are a powerful way of defining contracts within your code and contracts with code outside of your project.

First, create a new file in the src folder called UserInterface.ts and add:

export default interface User{
        name: string;
        age: number;
        address: string;
        dob: Date;

The code block above defines a simple User interface, which I will pass in as props into a new component. Because this interface is strongly typed, notice you cannot pass an integer for the name key, as the value is a string.

Declare a new component called UserComponent.tsx in the src folder and add:

import * as React from "react";

import UserInterface from './UserInterface'

export default class UserComponent extends React.Component<UserInterface, {}> {

constructor (props: UserInterface){
  render() {
    return (  <div>
              <h1>User Component</h1>
                Hello, {this.props.name}
                You are {this.props.age} years old,
                You live at: {this.props.address}
                you were born: {this.props.dob.toDateString()}


The code block above is pretty self-explanatory. I have imported the UserInterface created earlier on and passed it as the props of the UserComponent. In the constructor, I re-check that the props passed in are of the UserInterface type. In the render function, I printed the details out.

Next, alter your app.tsx file to:

import * as React from "react";
import * as ReactDOM from "react-dom";
import FirstComponent from './src/FirstComponent'
import UserComponent from './src/UserComponent'
<h1>Hello, Welcome to the first page</h1>
<UserComponent name="Logrocket" age={105} address="get me if you can" dob={new Date()} />

If you run the npm run magic command, and you navigate to your browser, you will see:


In this tutorial, you have (hopefully) learned how to use TypeScript with React. You have also learned how to configure webpack with ts-loader to compile the TypeScript files and emit a final build.

The code base for this tutorial is available here for you to play around with.

Full visibility into production React apps

Debugging React applications can be difficult, especially when users experience issues that are hard to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, try LogRocket.

LogRocket is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — .

Ogundipe Samuel Software engineer and technical writer.

3 Replies to “Using TypeScript with React: A tutorial”

  1. This is the error I get when first running `npm run magic`

    nvalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
    – configuration.module has an unknown property ‘loaders’. These properties are valid:
    object { defaultRules?, exprContextCritical?, exprContextRecursive?, exprContextRegExp?, exprContextRequest?, generator?, noParse?, parser?, rules?, strictExportPresence?, strictThisContextOnImports?, unknownContextCritical?, unknownContextRecursive?, unknownContextRegExp?, unknownContextRequest?, unsafeCache?, wrappedContextCritical?, wrappedContextRecursive?, wrappedContextRegExp? }
    -> Options affecting the normal modules (`NormalModuleFactory`).
    Did you mean module.rules or module.rules.*.use?

    bundle.js is never created. Don’t know how to get past this.

Leave a Reply