How to Use TypeScript with React

Amit Gilad
Bits and Pieces
Published in
6 min readJul 2, 2018

--

Using TypeScript with React, we get an excellent developer experience compared to what is provided by other frameworks. TypeScript can be helpful to React developers in a lot of ways.

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 app, such as an object which contains other properties. This results in strict checks which in turn reduces the amount of possible bugs that you might have produced without it.

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 also helps make the code more readable.

In this post, I will show you how to use TypeScript to improve the code of a React app by opening the syntax for self documenting code.

Tip: Use Bit to share and reuse React components between apps. You can discover and play with components, and install them to build faster. Try it.

React spinners with Bit: Choose, play, use

Getting started with examples

Installation

Let’s start by creating a simple React Project using create-react-app. In your command terminal, type:

$ create-react-app typescript-react
$ cd typescript-react

This command will create a new React project directory named typescript-react in your folder. Let’s make some changes inside this project so that we can use TypeScript.

Let’s start by installing a couple of packages as dependencies to this project. Along with things like webpack and webpack-dev-server, we also need to install the typescript package and TypeScript specific modules like @types/react and @types/react-dom. We also need the ts-loader for webpack.

$ yarn add webpack webpack-cli webpack-dev-server typescript @types/react @types/react-dom ts-loader

Configuration

Open the project directory in a code editor that supports TypeScript (I ❤️ VS Code) and take a look at the package.json file. Rewrite the scripts objects as shown below:

"scripts": {
"build": "webpack ./webpack.config.js",
"start": "webpack-dev-server ./webpack.config.js --content-base ./public"
}

Here, the start script uses the webpack.config.js file to run the webpack-dev-server for live application development and serves up the ./publicfolder. Create this file inside the root of the directory and write the following code inside it:

module.exports = {
devtool: 'inline-source-map',
entry: './src/app.tsx',
output: {
path __dirname + '/public',
filename: 'build/app.js'
},
resolve: {
extensions: ['.ts', '.tsx', '.js']
},
module: {
rules: [
{test: /\.tsx?$/, loader: 'ts-loader'}
]
}
}

Here, inline-source-map is used to debug TypeScript files within the browser. ./src/app.tsx is specified as the entry point. I’ve also specified a location for the built bundle inside the output object. We also need to inform webpack that it needs to support all files that have a .ts, .tsx or .jsextension. Finally, we need to tell webpack to use ts-loader for .tsand .tsx files.

Inside the public folder, delete everything except the index.html file. Rewrite the code inside this file as shown below:

<!DOCTYPE html>
<html lang="en">
<body>
<div id="root"></div>
<script src="./build/app.js"></script>
</body>
</html>

This code has a simple div with an id of “root” where we will render the React app, and then loads the bundle that is generated by the webpack.

Next, let’s write some configuration for TypeScript. Create a tsconfig.jsonfile inside the root of the directory and write the following code inside it:

{
"compilerOptions": {
"sourceMap": true,
"module": "commonjs",
"target": "es5",
"jsx": "react"
},
"include": [
"src"
],
"compileOnSave": false
}

The sourceMaps is enabled in order to debug the TypeScript files within the browser. We also need to tell TypeScript that we are using commonjs for the module format targeting es5. But most important piece of code here is the one that tells jsx to transpile to React.createElement. After that we need to tell TypeScript that the source code is present inside the src folder. Disable TypeScript‘s compileOnSave because that will be handled by webpack.

Verify

Delete all the files inside the src folder and create a new file named app.tsxwith the following code inside it:

import * as React from 'react';
import * as ReactDOM from 'react-dom';
ReactDOM.render(
<div>Use TypeScript with React</div>,
document.getElementById('root')
);

Run the start script using NPM or Yarn. This will start up webpack’s development server and serve the public folder at localhost:8080.

Stateless React Components in TypeScript

Writing stateless React components in TypeScript is simple. Open the app.tsx file inside the src folder and move the div inside the renderfunction to a stateless component.

import * as React from 'react';
import * as ReactDOM from 'react-dom';
const App = () => <div>Use TypeScript with React</div>;ReactDOM.render(
<App />,
document.getElementById('root')
);

By using components, we can leverage props to change the component’s behavior. Pass a prop named message to the App component and use it inside the function body.

const App = ({message}) => <div>{message}</div>;

TypeScript will now give us an error saying that the message prop needs to be provided. To resolve this error, re-write the render function as follows:

ReactDOM.render(
<App message="Use TypeScript with React"/>,
document.getElementById('root')
);

This works great for stateless functions. We can take this a step further and annotate this function as React.SFC. Re-write the App component as follows:

const App: React.SFC<{message: string}> = ({message}) => <div>{message}</div>;

And you can also take the inline prop type definition and move it into a type :

type AppProps = {message: string}
const App: React.SFC<AppProps> = ({message}) => <div>{message}</div>;

Stateful React Components using TypeScript

To create a stateful component in React, we need to extend the React.Component class. This class takes two generic parameters, props and state.

Open the app.tsx file inside the src folder and re-write the App component as a stateful component as shown below:

class App extends React.Component {
render() {
return(
<div>Use TypeScript with React</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('root')
);

Similar to stateless components, we can use props to change the behavior of the component. React.Component takes the props as its first argument:

class App extends React.Component <{
message: string
}>
{
render() {
return (
<div>{this.props.message}</div>
);
}
}
ReactDOM.render(
<App message="Use TypeScript with React"/>,
document.getElementById('root')
);

Such components which extend React.Component are called stateful because they can have their own internal state. React.Component takes a second generic argument that specifies the type of the state.

class App extends React.Component <{
message: string
}, {
count: number,
}
> {
constructor(props) {
super(props);
this.state = {
count: 0
}
}

render() {
return(
<div>{this.props.message}{this.state.count}</div>
);
}
}

Here, I’m creating a state called count of type number. This state is then initialized inside the constructor. We can then use this state in other places, like the render method.

The main reason for having a local state in a component is that you get to manage it inside the component. Inside the App component, create a new function called increment.

increment = () => {
this.setState({
count: this.state.count + 1
});
}

Call this function on the div that is inside the components render function.

render() {
return (
<div onClick={this.increment}>{this.props.message}{this.state.count}</div>

The state will now change whenever the user click on the div that is rendered on the browser.

Conclusion

In this post, you saw how TypeScript can be used to make the code of our React apps more maintainable and readable.

  • We started with learning about the packages that are required to make TypeScript compatible with React.
  • You then saw how to configure TypeScript to accept React code, and how to configure Webpack to render this code on a browser.
  • Finally, we learned how to write simple stateless and stateful React Components with TypeScript.

--

--

core developer at bitsrc, JavaScripter evangelist & open source contributor