Editor’s note: This guide to using TypeScript with React was last updated on 2 August 2022 to include an overview of TypeScript’s benefits when combined with React and information about .tsx files.
In this tutorial, you’ll learn everything you need to know about using TypeScript in your React projects. You’ll also learn why you should use TypeScript in React, how to install and configure TypeScript, and how to use TypeScript interfaces with React components.
We’ll cover the following with examples:
- What is React?
- What is TypeScript?
- Is React better with TypeScript?
- Understanding
.tsx
files in Typescript - Installing and configuring TypeScript
- How does TypeScript compile React code?
- Configuring webpack for React and TypeScript
- Adding
npm
scripts - Creating the
index.tsx
file - Creating React components in TypeScript
- Using TypeScript interfaces with React components
What is React?
Created by Facebook and originally open sourced in 2013, React has become one of the most popular libraries in the frontend world today. React is easily extendable and can include features such as routing and 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 at a high level, check out the official React documentation.
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.
A superset of JavaScript
JavaScript was initially created as a client-side language, but over time, developers understood that JavaScript could be used on the server, especially with the invention of the v8 engine.
JavaScript can quickly become complex and sometimes can’t live up to the full potential of an object-oriented programming language. TypeScript was born to bridge this gap and to become an alternative for enterprise-level development.
TypeScript emits JavaScript when compiled and is a popular name in the JavaScript world today. Even pure JavaScript applications ship a type.d.ts
type definition for TypeScript developers.
Is React better with TypeScript?
TypeScript can be helpful to React developers in many ways. Below are just a few benefits of using TypeScript in React:
Variable and bug checks
TypeScript offers variable checks by checking the data type assigned to statically-defined variables. This overall reduces the possibility of assigning the wrong types to our variables.
TypeScript also does compilation time checks that help flag errors such as wrong parameter assignments, syntax errors, and so much more. This is great because it reduces the likelihood of calling the wrong function or accidentally skipping a variable declaration.
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 language variables are type-checked.
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 that contains other properties. This results in strict checks, which reduce the number of possible bugs you may produce without it.
Better support for JSX
JSX stands for JavaScript XML. It allows us to write HTML code directly in our React project. Using TypeScript with React provides better IntelliSense and code completion for JSX.
IDE support
TypeScript is also very helpful while using IDEs like Visual Studio, Visual Studio Code, Atom, Webstorm, Eclipse, and so many more. These provide better autocomplete and snippet generation, making development faster.
Support for existing React projects
TypeScript allows you gradually adapt its usage in your existing projects. You can also configure the TypeScript compiler for this use case. Find a list of TypeScript compilers in the official TypeScript documentation.
Community
Finally, TypeScript is an open source language backed by Microsoft. It’s widely loved and used by millions of developers worldwide. Because it’s so widely used, it’s easy to find support and answers to your questions if you get stuck while learning or using TypeScript.
Understanding .tsx
files in TypeScript
The introduction of .tsx
in TypeScript came several releases after TypeScript v1.0. According to the release notes for TypeScript v1.6 where .tsx
extension was introduced, the new extension was designed to do two things:
- Enable JSX inside of TypeScript files
- Make the new
as
operator the default way to cast
The introduction of .tsx
also resulted in three additional things:
- JavaScript bundlers like webpack, ESBuild, and others can run different plugins for
.tsx
files - Test runners like Jest can run a different test environment only for
.tsx
files - New language support by code editors
Difference between .ts
and .tsx
in TypeScript
The introduction of .tsx
file extension caused the need for clarification. Many developers wanted to know the difference between the new file extension and the already existing .ts
.
The difference is actually pretty straightforward! The .ts
file extension is used when you are creating functions, classes, reducers, etc. that do not require the use of JSX syntax and elements, whereas the .tsx
file extension is used when you create a React component and use JSX elements and syntax.
Installing and configuring TypeScript
Now that we’ve gone over a general overview, let’s get to the installation. There are two ways to install and get started with TypeScript
- Using
npm
- Using
create-react-app
To install TypeScript using npm
, run the following in your terminal:
npm install -g typescript
Because we installed TypeScript globally, we need to link it so that npm
knows the location.
To do this, we run:
npm link typescript
Once npm is done, you can verify that TypeScript is installed correctly:
tsc --v // Version 4.7.4
The above will print out the version number of TypeScript installed.
To get started with a project after successful installation, create a folder that will hold the application.
More great articles from LogRocket:
- Don't miss a moment with The Replay, a curated newsletter from LogRocket
- Learn how LogRocket's Galileo cuts through the noise to proactively resolve issues in your app
- Use React's useEffect to optimize your application's performance
- Switch between multiple versions of Node
- Discover how to animate your React app with AnimXYZ
- Explore Tauri, a new framework for building binaries
- Advisory boards aren’t just for executives. Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Create a new directory:
mkdir typescript-react-project
Change directory to the new folder:
>cd typescript-react-project
Initiate the project:
npm init
To install TypeScript with create-react-app
, run the following one-liner in your terminal:
npx create-react-app .
The command above will create a simple folder structure for your application, then install all the necessary modules and get your project up and running for you.
For this tutorial, we’ll use the npm init
method.
How does TypeScript compile React code?
TypeScript always checks for a file called tsconfig.json
in the project root folder for instructions. When it finds the tsconfig.json
file, it loads the settings defined in the file and uses them to build the project.
A TypeScript project is compiled in one of the following ways:
- By invoking
tsc
with no input files, in which case the compiler searches for thetsconfig.json
file starting in the current directory and continuing up the parent directory chain - By invoking
tsc
with no input files and a--project
(or just-p
) command line option that specifies the path of a directory containing atsconfig.json
file, or a path to a valid.json
file containing the configurations
When input files are specified on the command line, tsconfig.json
files are ignored.
If you do not have the tsconfig.json
file in your root folder, go ahead to create it and add the following code:
{ "compilerOptions": { "outDir": "./dist/", "noImplicitAny": true, "module": "es6", "target": "es5", "jsx": "react", "allowJs": true, "moduleResolution": "node", } }
The JSON configuration above defines two major sections: the compilerOptions
and exclude
parameters.
In the compiler options, a target of es6
has been set. This means the JavaScript engine target will be set to es6
but will compile down to es5
as the target. 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
. The outDir
is the output folder after compilation.
In the exclude
block, node_modules
is 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 might wonder why the include
section is missing. This is because we’re going to configure webpack
to handle taking in the entry files, passing them to TypeScript for compilation, and returning a bundled JavaScript script for browsers.
You can learn more about other configuration options in the TypeScript docs.
Configuring webpack for React and TypeScript
webpack is a tool that lets you compile JavaScript modules and is also known as a module bundler.
To get started with webpack in TypeScript, we need to install webpack and a webpack plugin called ts-loader
. To do this, run the following command in the terminal:
npm install webpack webpack-cli ts-loader
What is ts-loader
? As its name implies, ts-loader
is the TypeScript loader for webpack. Put simply, 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.
If it doesn’t already exist, create a new file called webpack.config.js
and add the following code:
const path = require('path'); module.exports = { entry: './src/index.tsx', module: { rules: [ { test: /\.tsx?$/, use: 'ts-loader', exclude: /node_modules/, }, ], }, resolve: { extensions: ['.tsx', '.ts', '.js'], }, output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist'), }, };
The code above will direct webpack to enter through the ./src/index.ts
file, load and compile all the .ts
and .tsx
files through the ts-loader
, and then output a bundle.js
file in our dist
directory.
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 the package.json
file in the project root directory and update the scripts
section with:
"scripts": { "magic": "webpack" }
Creating the index.tsx
file
After all the configurations were done above, it’s time to create the main entry point file of our project, but before we do that, we need to install the following:
npm install react react-dom @types/react @types/react-dom
Next, create a new folder src
and then a file in the src
folder called index.tsx
in the root and add the following code:
import * as React from "react"; import * as ReactDOM from "react-dom"; ReactDOM.render( <div> <h1>Hello, Welcome to React and TypeScript</h1> </div>, document.getElementById("root") );
Above is a simple React setup, except that it is using TypeScript. To compile the file, run the command below in your terminal:
npm run magic
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> <html> <head> <meta charset="utf-8"> <title>Getting Started with Typescript and ReactJS</title> </head> <body> <!-- this is where react renders into --> <div id="root"></div> <script src="dist/bundle.js"></script> </body> </html>
If you double click on the index.html
file to open it in a browser, you will see:
Creating React components in TypeScript
Now that we’re great with the basics of writing React in TypeScript, let’s dive into how we can create React components, as this is an essential part of developing our application.
In the already created src
folder, we’ll add a folder called components
. This is the folder that will hold any React component we create. In the components
folder, go ahead to create a new file called FirstComponent.tsx
and add the following code:
import * as React from "react"; let Logo ="https://logrocket-assets.io/static/home-hero-c97849b227a3d3015730e3371a76a7f0.svg"; export default class FirstComponent extends React.Component <{}> { render() { return ( <div> <h3>A Simple React Component Example with Typescript</h3> <div> <img height="250" src={Logo} /> </div> <p>This component shows the Logrocket logo.</p> <p>For more info on Logrocket, please visit https://logrocket.com </p> </div> ); } }
The above code block is a simple React component that returns a logo and some text.
To make this new component accessible to React, we need to import and use the component in the base index.tsx
file. Update the index.tsx
file to:
import * as React from "react"; import * as ReactDOM from "react-dom"; import FirstComponent from './components/FirstComponent' ReactDOM.render( <div> <h1>Hello, Welcome to React and TypeScript</h1> <FirstComponent/> </div>, document.getElementById("root") );
Looking at the code block above, you see that the differences are on lines 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.
To see how you can use interfaces with your react components, create a file UserInterface.ts
in the src
folder and add the following code:
export default interface User{ name: string; age: number; address: string; dob: Date; }
The code block above defines a simple User interface, which will be passed 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.
Create a new component in our components
folder called UserComponent.tsx
and add the following code:
import * as React from "react"; import UserInterface from '../UserInterface' export default class UserComponent extends React.Component<UserInterface, {}> { constructor (props: UserInterface){ super(props); } render() { return ( <div> <h1>User Component</h1> Hello, <b>{this.props.name}</b> <br/> You are <b>{this.props.age} years old</b> <br/> You live at: <b>{this.props.address}</b> <br/> You were born: <b>{this.props.dob.toDateString()}</b> </div> ); } }
The code block above is very self-explanatory. The UserInterface
created earlier on has been imported and passed down as the props of the UserComponent
. In the constructor, we checked that the props passed are of the UserInterface type and in the render function, the data will be displayed on our page.
After creating our UserComponent
, update the index.tsx
file:
import * as React from "react"; import * as ReactDOM from "react-dom"; import FirstComponent from './components/FirstComponent' import UserComponent from './components/UserComponent' ReactDOM.render( <div> <h1>Hello, Welcome to React and TypeScript</h1> <FirstComponent/> <UserComponent name="John Doe" age={26} address="87 Summer St, Boston, MA 02110" dob={new Date()} /> </div>, document.getElementById("root") );
Now run npm run magic
, navigate to your browser and view the updated changes. You should see:
Conclusion
In this tutorial, we demonstrated how to use TypeScript with React. We also walked through how to configure webpack
with ts-loader
to compile the TypeScript files and emit a final build.
The codebase for this tutorial is available here for you to play around with on GitHub.
Get setup with LogRocket's modern React error tracking in minutes:
- Visit https://logrocket.com/signup/ to get an app ID.
- Install LogRocket via NPM or script tag.
LogRocket.init()
must be called client-side, not server-side. - (Optional) Install plugins for deeper integrations with your stack:
- Redux middleware
- ngrx middleware
- Vuex plugin
$ npm i --save logrocket
// Code:
import LogRocket from 'logrocket';
LogRocket.init('app/id');
Add to your HTML:
<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>
This really helped, thank you!
Nice article, but I think maybe you need to fix the contents of tsconfig.json (looks like you pasted the webpack config contents there.)
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.
By far the best introduction into React used together with TypeScript. Nice and simple project. Thumbs up for that 🙂
This seems like a great guide but I can’t get this to work with Ubuntu 20.04. When I run “npm link typescript”, I get a few errors, such as gulpfile not found and such. Perhaps it’s something with my operating system but this guide isn’t one I can recommend to anyone. I’ll change my stance once my issue gets resolved.
I got the same error. Eventually discovered this error will occur if no linking is necessary. I proceeded to verify typescript version and complete the tutorial successfully, despite the gulpfile error.
can i run the project using npm start? or should i use a different command?