TypeScript and React are a great match, which already becomes clear during the setup of a project.
The setup isn't as complicated as you may think, as TypeScript already includes all the features needed for compiling React's JSX code to JavaScript. You won't even need Babel anymore when you're finished.
In this article, I'll first explain how to configure TypeScript with the tsconfig
file. Afterward, we'll see how to set up an entire project using Webpack or Create React App.
Dependencies
To get started with TypeScript, we need to install the typescript
package together with React's type definitions.
yarn add typescript @types/react @types/react-dom
Many npm packages already include the type definitions out of the box. If they are missing, we'll see compilation errors, in which case we can usually install the matching types:
yarn install -D @types/module-name
React tsconfig.json setup
The tsconfig.json
file is the place where we make TypeScript work together with React.
In this section, I'll explain the most important settings.
JSX
JSX is a syntax that combines JavaScript with a templating language that looks similar to HTML. If you were using React before, you're already familiar with it.
A <div />
in JSX compiles to the following JavaScript code:
React.createElement('div')
In React, we use Babel for compiling JSX to JavaScript syntax, but TypeScript is also capable of doing this if we set the jsx
field to react
.
{
"compilerOptions": {
"jsx": "react",
...
}
}
We might also set this field to preserve
, which won't compile the JSX syntax when we want to use Babel for compiling JSX.
lib
With the lib
field, we specify the libraries we want to include in the build.
{
"compilerOptions": {
"lib": ["es6", "dom"],
...
}
}
ES6 gives us modern JavaScript features, while DOM adds typings for browser-specific things like HTML, Events, and more.
target
If we want to have better compatibility with older browsers, we can use target
to specify the ECMA Script version we want to support.
{
"compilerOptions": {
"target": "ES6",
...
}
}
I usually set this to ES6, as this already supports more than 97% of all internet users, which is more than enough for most people.
Synthetic imports
By default, imports in TypeScript have the following syntax:
import * as React from 'React';
If we want to keep importing our modules as we did with Babel, we need to change some settings in our tsconfig file.
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
...
}
}
After this, we can deconstruct our imports again and avoid the obligatory asterisk *
.
import React, { FC } from 'react';
Strict checks
We can make our TypeScript configuration as strict or relaxed as we want.
Even when just getting started, I recommend you turn on the noImplicitAny
setting, which will make the compiler throw an error when we forget to specify a variable's type.
If you want to avoid TypeScript to compile code with errors, you can also enable the noEmitOnError
option.
{
"compilerOptions": {
"noImplicitAny": true,
"noEmitOnError": true,
...
}
}
The noImplicitAny
option will make the following code throw a compilation error.
const logValue = (value) => console.log(value);
const logValue = (value: string) => console.log(value);
I like this option because it makes sure I don't forget to add types. If needed, I can explicitly add any
to bypass this rule (not recommended).
Other rules that increase TypeScript's strictness are noImplicitReturns
, noImplicitThis
, and strictNullChecks
.
React tsconfig.json example
Putting everything together, we end up with a file that looks like the following.
{
"compilerOptions": {
"outDir": "dist",
"rootDir": "src",
"sourceMap": true,
"noImplicitAny": true,
"allowSyntheticDefaultImports": true,
"allowJs": true,
"moduleResolution": "node",
"module": "commonJS",
"lib": ["es6", "dom"],
"target": "ES5",
"jsx": "react"
},
"exclude": [
"node_modules",
"dist"
]
}
I explained the most important ones you need to get started.
Next, we'll see how to set up TypeScript with Create React App and Webpack.
TypeScript with CRA (Create React App)
The easiest way to start a new React project with TypeScript is by using Create React App.
Using the official TypeScript template, you'll get a fully configured project to get started.
npx create-react-app my-new-ts-project --template typescript
Adding TypeScript to an existing CRA project
The setup for already existing CRA apps is as easy as it gets.
All you need to do is to install the following packages, and you're good to go. You don't even need to create a tsconfig file!
yarn add typescript @types/node @types/react @types/react-dom @types/jest
The next step is to rename any file to have the TypeScript extension (.ts
or .tsx
) and restart your development server.
You can then gradually move your components to TypeScript.
Adding a tsconfig.json
file to the root of your project will override the default settings.
TypeScript with Webpack
The first step is to install ts-loader
and typescript
(if you haven't already).
yarn add typescript ts-loader
With these packages installed, we now modify our webpack.config.js
file to use TypeScript.
module.exports = {
entry: './src/index.ts', module: {
rules: [
{ test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, ],
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ], },
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
};
We're now using ts-loader
to compile all our source files.
Add TypeScript to an existing webpack project
If you have an already existing project that you want to migrate, you can do so in small steps, using babel-loader
for your JavaScript files and ts-loader
for TypeScript.
...
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
{
test: /\.tsx?$/,
include: path.resolve(__dirname, '../src'),
exclude: /node_modules/,
use: 'ts-loader',
},
...
Afterward, you can migrate your project step by step. You can find more information on how to do this in the TypeScript documentation.
Conclusion
That's it! You should now be able to use TypeScript in your React applications. The initial set up can be a bit of effort, but you're now able to enjoy the benefits of a typed language.
In my next article, I'll explain how you can create React components with TypeScript. Make sure to check it out, and if you liked this one, consider subscribing to my email list below.