DEV Community

Cover image for Typescript in React
Jareth Tan
Jareth Tan

Posted on

Typescript in React

Table Of Contents

1. Introduction
2. Functionalities and Examples
3. Conclusion

Another week, another post. Carrying on from my previous post about Typescript for beginners, I thought I would write a post about using typescript in a React application for beginners.

Introduction
As the popularity of React exploded in recent years, the demand to build React applications using Typescript has increase significantly as well.

Adding Typescript to React

I typically use create-react-app boilerplate to start my react application. To add Typescript when creating our react app, just type this additional wordings:

npx create-react-app my-app --template typescript
Enter fullscreen mode Exit fullscreen mode

Once the boilerplate is completed, open the file and we will notice that some files are named .ts or .tsx. There is also a new file generated called tsconfig.ts. This file is where all the magic happens for Typescript. Typescript looks for the tsconfig.json file in the project root folder, and that file provides configuration options for the compiler.

Functionalities and Examples

Before we jump into the use cases of Typescript in React, lets have a quick overview on the different "Types" in Typescript.

  • void: denotes the absence of any type.
  • tuple: works like an array, but the number of elements here is fixed. The types of elements in a tuple are known and can be of different types.
  • enum: is a group of constant values that are closely related and known.
  • any: allows us to assign the value of any type to a variable. Used when a value type is unknown
  • never: is a type that contains no value, so we can’t assign any value to a variable with a never type.
  • union: this describes a value that can be one of several types number | string | boolean
  • object: To define an object type we list its properties and their types: {x:number, y:number}

There is a deeper dive on this types in the previous post. Do check it out for more information on this.

React functional components
With the release of react 16.8, majority of users have shifted away from using class components to functional components. A React Functional Component is a function that receives props objects and returns JSX elements. In React components, we need to consider the type of props coming in. Integrating Typescript with functional component is pretty straight forward as follows:

import {FC} from "react"

const Movies: FC<{title: string}> = ({ title }) => {
  return (
    <>
      <h1>{message}</h1>
    </>
  );
};
Enter fullscreen mode Exit fullscreen mode

This is one of the ways to define a functional component with Typescript. We have assigned a FC type to the functional component. Well, FC is an alias for Function Component. Also, noticed we have assigned types for the props being passed into the component by declaring it right after FC.

Interface
Another way of assigning types to your props is by using an interface. Typescript interfaces are essential to enforcing a particular object shape. An interface is like an object that contains information about the object’s properties and types. It explicitly tells the Typescript compiler about the property names and the value types an object can have. Also, since TypeScript is able to infer the type of your variables, you can remove typing the component FC as well. So in the end, it will look like this:

import {FC} from "react"
// we can do it like this
const Movies: FC<{title: string, boxOffice: number}> = ({ title, boxOffice }) => {
  return (
    <>
      <h1>{message}</h1>
    </>
  );
};

// or with an interface
interface MovieProps{
 title: string;
 boxOffice: number;
}

const Movies = ({ title, boxOffice }: MovieProps) => {
  return (
    <>
      <h1>{message}</h1>
    </>
  );
};

// To keep the title prop optional. Just pass it this way
interface MovieProps{
 title?: string;
 boxOffice: number;
}
Enter fullscreen mode Exit fullscreen mode

There are a few advantages for using interfaces. Firstly, the code is a little cleaner. Secondly, we can export the interface and use it in other parts of our code as a type as well by doing this: export interface MovieProps which ensures consistency in our code. We can also define our interfaces in a single file and reference from that file. Any changes made can also be made in one location.

Some React Hooks

useState
For useState hooks, the type expected can be inferred from the initial value passed into useState. For example:

const [title, setTitle] = useState("");
// is equal to
const [title, setTitle] = useState<string>("");
Enter fullscreen mode Exit fullscreen mode

Since an empty string is passed as an initial value, typescript has inferred that the value stored will be a string type. However, if we are going set initial value as null or undefined, we need to pass a union of types like this:

const [title, setTitle] = useState<string | null>(null);
Enter fullscreen mode Exit fullscreen mode

And if we are expecting an object in the useState hook, we can use interface to define the object type and assign it as a type in useState.

useRef
In most cases, useRef is used to reference input elements in HTML. Something like this:

function movieSearch() {
  const inputTitle = useRef(null);
  return (
    <>
      <input ref={inputTitle} type="text" />
    </>
  );
}
Enter fullscreen mode Exit fullscreen mode

In such cases, we can use a generic type and note that we dont need to assign null as a type for generic types as it accepts null already.

const inputTitle = useRef<HTMLInputElement>(null)
Enter fullscreen mode Exit fullscreen mode

useEffect
Typing the useEffect hook is not required because they don’t deal with returning values. The cleanup function for the useEffect hook is not considered a value that can be changed either so we can write these hooks as normal.

HTML events
The most commonly HTML events are button events, onChange events and form submits. These are the following example on how to type those events.

import { useState, ReactElement, ChangeEvent, FormEvent } from "react";

const App = (): ReactElement => {
  const [title, setTitle] = useState<string | null>(null);
  const handleSubmit = (e: FormEvent) => {
    e.preventDefault();
    // handle event here...
  };
  return (
    <form onSubmit={handleSubmit}>
      <div>
        <span>Email:</span>
        <input
          type="email"
          name="email"
          onChange={(e: ChangeEvent<HTMLInputElement>) =>
            setTitle(e.currentTarget.value)
          }
        />
      </div>
      <div>
        <input type="Submit" value="Submit" />
      </div>
    </form>
  );
};
Enter fullscreen mode Exit fullscreen mode

As seen from above, the events for submitting the form is typed as FormEvent as import from the react node module. As for the change event, it is typed as ChangeEvent<HTMLInputElement> as onChange prop is in an input element which handles a change event. as for button events, it is shown as:

<button onClick={ (e: MouseEvent<HTMLButtonElement, MouseEvent>) => console.log("Clicked")}>button</button>
Enter fullscreen mode Exit fullscreen mode

Do note that for most of the time, button and change event types can be inferred by Typescript hence there is no need to explicitly assigned the types to such events.

Conclusion
Well, there we go, this are the more commonly used types when using React with Typescript. This list is by no means exhaustive and I do realize I have not covered some critical parts such as generics, type definition for some hooks (useContext or useMemo) or typing different type of React components. However I have not apply Typescript consistently on these topics or understand the core concepts behind them to write about it confidently yet. Once I do, I will update this blog post with more information. For now, I believe the information in this post is sufficient enough to get start with Typescript in a React application. As always, more information can be found in the official document: https://www.typescriptlang.org/docs/handbook/react.html
Till next time. Take care and stay safe.

Top comments (0)