JavaScript

Using TypeScript in a React Application

TypeScript has been developed by Microsoft as an open-source project since 2012.

 

The way it works is fundamentally different from Flow. Whereas Flow focuses on type markup and leaves the rest of the source code untouched, TypeScript is a programming language in its own right that extends the core of JavaScript and adds other features.

 

Basically, valid JavaScript code is also valid TypeScript code. However, this statement isn’t true in the other direction. Trying to run TypeScript directly in the browser usually results in syntax errors and termination of the application. TypeScript has become the de facto standard for type-safe JavaScript in recent years.

 

In any case, you should consider using a type system for your application, as the advantages clearly outweigh the disadvantages. As a type system, we clearly recommend TypeScript, as it has a much higher penetration in the community and is also very well supported by the various add-on libraries for React.

 

Integrating TypeScript in a React Application

The combination of React and TypeScript has been supported for quite some time. TypeScript wasn’t officially included in Create React App until version 2.1 in October 2018. Since the release of this version, it’s possible to start the development of an application directly with TypeScript. Meanwhile, the Create React App team has tweaked the architecture a bit so that you can specify a template for creating your app. One of the default templates is named typescript and initializes a React application with TypeScript support for you. Below shows the command you use to initialize the application with TypeScript:

 

npx create-react-app library --template typescript

 

By using the --template typescript option, you make sure that Create React App installs all the dependencies required to use TypeScript in your application. It also creates the necessary structures and configurations so that you can start developing right away. The development and build process is also modified accordingly.

 

The first difference from an ordinary React application is the presence of the tsconfig.json file in the root directory, which can be used to configure the behavior of TypeScript. Also, unlike Flow, TypeScript doesn't give you the option to selectively check only part of the files; you have to do this with all the files in your application. The component files also have the extension .tsx, which should indicate that it is a combination of TypeScript and JSX. For helper files that don’t contain JSX, you can use the .ts extension. For demonstration purposes, you can use the source code from this listing.

 

import React from 'react';

import './App.css';

 

const App: React.FC = () => {

   let name: string = 'World';

   name = 42;

   return (

       <div className="App">

         <h1>Hello {name}</h1>

      </div>

   );

}

 

export default App;

 

When you use TypeScript, you can omit the explicit specification of the type. The first assignment of a value to a variable simultaneously determines its type. Otherwise, TypeScript behaves very similarly to Flow in the case of faulty source code, as in this example.

Execution in the Development Environment

TypeScript is supported by all major development environments, such as WebStorm or Visual Studio Code. The source code is checked immediately upon its creation, and errors are displayed right away. With this direct feedback, many errors can be found and fixed before the source code is executed. Also, the suggestions that the development environment gives you when writing the source code are significantly better than when using pure JavaScript because the signature of functions and the structure of objects are known. The figure below shows an error message you might get for incorrect source code when you open it in Visual Studio Code.

 

TypeScript Error Message in Visual Studio Code

 

You can use TypeScript not only in the development environment, but also in the command line, and thus integrate it into an automated build process, for example.

Execution in the Command Line

At the core of TypeScript, there is the TypeScript compiler or tsc. This command-line tool checks the TypeScript source code of your application and transforms it into valid JavaScript source code that can be run in the browser. For this transformation to work, the typescript package must be installed on your system. Create React App will do the installation for you. After the installation, you can write TypeScript and transform the code using the default TypeScript configuration. Alternatively, you can use the tsc -- init command to have a configuration generated in the form of tsconfig.json. This affects the way the TypeScript compiler works. In the current example, such a configuration file already exists, and you only need to switch to the command line and enter the npx tsc command. The compiler automatically finds the configuration file and applies it. In this listing, you can see the output in the command line.

 

$ npx tsc

src/App.tsx:7:3 -

   error TS2322: Type 'number' is not assignable to type 'string'.

 

7 name = 42;

   ~~~~

 

Found 1 error in src/App.tsx:7

 

The current configuration of TypeScript ensures that no JavaScript source code is stored in the file system during the development process. This isn’t necessary because TypeScript is very deeply integrated into the development process. With npm start, you run the application directly based on Webpack with the dev server. For production use, you need to have the source code translated to JavaScript. The npm run build command will help you with this. It creates an executable application for you, which you can deploy to any web server. With this knowledge, you can now dive deeper into the world of TypeScript.

 

The following explanations and examples of TypeScript are significantly more extensive than those for Flow as the rest of the book is based on TypeScript. The reasons for this are mainly that TypeScript is much more powerful compared to Flow and that it has a wider distribution.

 

Configuration of TypeScript

You can influence the behavior of the TypeScript compiler through options in the command line or through the tsconfig.json file. If such a file exists in the root directory of your application, where you also run the compiler, the file is used automatically and you don’t need to reference it explicitly.

 

The most important specifications in the configuration are the compilerOptions, which you can use to control the compiler, and include, which you can use to specify a list of directories that contain the files with the TypeScript source code. If necessary, you can use the exclude key to exclude certain patterns from the compilation process and use files to specify individual files. In the listing below, you can see the default configuration for TypeScript that Create React App generates for you:

 

{

   "compilerOptions": {

      "target": "es5",

      "lib": [

         "dom",

         "dom.iterable",

         "esnext"

      ],

      "allowJs": true,

      "skipLibCheck": true,

      "esModuleInterop": true,

      "allowSyntheticDefaultImports": true,

      "strict": true,

      "forceConsistentCasingInFileNames": true,

      "noFallthroughCasesInSwitch": true,

      "module": "esnext",

      "moduleResolution": "node",

      "resolveJsonModule": true,

      "isolatedModules": true,

      "noEmit": true,

      "jsx": "react-jsx"

   },

   "include": [

      "src"

   ]

}

 

Usually, the default configuration should be sufficient for using React, so you’ll hardly come into contact with the configuration during the development process.

 

The Major Features of TypeScript

The differences in source code markup and key features are minor between Flow and TypeScript. However, the two differ seriously in the basic handling of the source code. TypeScript also supports basic data types such as Boolean, string, or number as well as composite data types such as objects and arrays. In addition, there are special data types such as enum, which you can use to map keys to values.

 

TypeScript allows the use of classes that represent types at the same time and thus can be used in type assignments. Type aliases, interfaces, and generics are also supported by TypeScript and used in React applications. In TypeScript, you can use modules, which are self-contained units that each reside in a file. The module syntax is the same as in the ECMAScript module system, so you can still use the import and export keywords in your application to import and export your modules, respectively.

 

Type Definitions: Information about Third-Party Software

TypeScript has a special feature when dealing with libraries written in JavaScript that are to be used in a TypeScript application. The interfaces of these libraries are usually not provided with type information, so you would lose most of the benefits of TypeScript at this point as the compiler would fall back to the implicit any type. If you use any, further type checking is no longer possible at this point.

 

To solve this problem, TypeScript provides a feature called type definitions that can be used to provide types to JavaScript interfaces. An increasing number of libraries in the React environment ship these type definitions right along with the actual source code so that the versions of the interface and the type definition are identical. Far more often, however, the type definitions are offered as an additional package. This creates the risk that the versions are different and you are working with a potentially outdated version of the interface definition. But type definitions are often also maintained by the people who created the libraries, so few problems are expected here.

 

DefinitelyTyped has established itself as the most important source. This is a repository from which you can obtain type definitions for numerous libraries. Type definitions are maintained in a GitHub repository (https://definitelytyped.github.io/) and can be selectively installed via a package manager such as Yarn or NPM. When installing a type definition, you want to make sure to install it as devDependency. Type definitions are used only during development and not for running your application.

 

To install the type definition for React, which Create React App automatically does for you, you need to run the npm install -D @types/react command. The @types prefix stands for the DefinitelyTyped repository. After the installation, you don't need to do anything else: you can work directly with the type definitions because TypeScript automatically looks for an @types directory in node_modules if there are no direct type definitions for a particular library.

 

Editor’s note: This post has been adapted from a section of the book React: The Comprehensive Guide by Sebastian Springer.

Recommendation

React: The Comprehensive Guide
React: The Comprehensive Guide

React.js makes developing dynamic user interfaces faster and easier than ever. Learn how to get the most out of the library with this comprehensive guide! Start with the basics: what React is and how it works. Then follow practical code examples to build an application, from styling with CSS to maximizing app performance. Whether you’re new to JavaScript or you’re an advanced developer, you’ll find everything you need to build your frontend with React!

Learn More
Rheinwerk Computing
by Rheinwerk Computing

Rheinwerk Computing is an imprint of Rheinwerk Publishing and publishes books by leading experts in the fields of programming, administration, security, analytics, and more.

Comments