How Does TypeScript Work with React?

How Does TypeScript Work with React?

Summary

  • TypeScript enhances React development by providing static type checking, improving code reliability and understandability.
  • Setting up TypeScript with React can be done either for a new project using Create React App or for an existing project by adding TypeScript dependencies and renaming files.
  • Vite can also be used to set up a TypeScript React project, providing a different approach compared to Create React App.
  • Basic TypeScript types such as String, Number, Boolean, Array, and Object are commonly used in React for defining props and state.
  • React hooks like useState, useEffect, and useCallback can be utilized in TypeScript with type annotations to improve code quality and prevent errors.
  • Creating TypeScript React components involves defining interfaces for props, typing hooks, and leveraging TypeScript’s type system for reliability and maintainability.
  • Testing React components with TypeScript involves setting up the testing environment, writing tests, and using advanced techniques like mocking and snapshot testing.
  • TypeScript checks types at compile time, ensuring that components receive correct props and handle them appropriately.
  • Integrating TypeScript into React projects may require additional setup but offers long-term benefits in terms of code quality and maintainability.
  • Understanding core TypeScript principles and applying best practices is key to maximizing the benefits of using TypeScript with React.

TypeScript and React have emerged as key players in today’s fast-paced world of web development. TypeScript, with its ability to provide static type checking, has become an invaluable tool for developers seeking to write more reliable and understandable code. React, on the other hand, is celebrated for its efficiency in rendering complex user interfaces with its component-based architecture. 

In this article, we’ll explore how TypeScript, a statically typed superset of JavaScript, enhances development with React, a popular JavaScript library for building user interfaces. TypeScript brings clarity and predictability to the code, making it easier for developers to catch errors early and manage large codebases more effectively. By the end of this article, you will have a clear understanding of how to use TypeScript with React to build robust web applications. Let’s start coding!

Basic TypeScript Types in React

Prop TypeExample Usage
Stringmessage: string;
Numbercount: number;
Booleandisabled: boolean;
Arraynames: string[];
Object with Known Propertiesobj: { id: string; title: string; };
Array of ObjectsobjArr: { id: string; title: string; }[];
Function (no return)onClick: () => void;
Function (with parameter and return)onChange: (id: number) => void;
Optional Propoptional?: OptionalType;

Also Read: Introduction to Redux for State Management

Setting Up Your Environment

For a New Project Using Create React App

Step 1: Starting a New Project

If you’re beginning a new project and want to use TypeScript, you can set it up directly when you create the app. Just open your terminal and type the following command:

npx create-react-app my-app –template typescript

Replace my-app with whatever you want to name your project. This command creates a new React application with TypeScript already set up.

Step 2: Install Dependencies

After running the command, it will set up the project and install the necessary dependencies for you. Once it’s done, you can move to the next step.

Step 3: Start Your Project

To see your new TypeScript React app in action, navigate into your project directory and start the development server:

cd my-app

npm start

This command runs your app in development mode. Open your web browser and go to http://localhost:3000 to see your app running.

For an Existing Project Using Create React App

If you already have a React project and you want to add TypeScript to it, follow these steps:

Step 1: Add TypeScript to Your Project

First, you need to add TypeScript and the types for React and ReactDOM. Run this command in your project’s root directory:

npm install –save typescript @types/react @types/react-dom

Step 2: Rename Files

Change your file extensions from .js to .tsx for files with JSX in them, or .ts for files without JSX. This tells the project that you’re now using TypeScript.

Step 3: Run Your Project

Just like before, use npm start to run your project. TypeScript will now be part of your build process, checking your code for errors.

For a Project Using Vite

If you prefer using Vite, here’s how to set up a TypeScript React project:

Step 1: Create a Vite Project

To start a new project with Vite and TypeScript, run:

npm create vite@latest my-vite-app — –template react-ts

Again, replace my-vite-app with your project name. This command creates a new project using Vite with a React and TypeScript setup.

Step 2: Navigate to Your Project

Move into your new project’s directory:

cd my-vite-app

Step 3: Install Dependencies

If your new Vite project needs any additional dependencies, install them now. Since you used the react-ts template, TypeScript and React type definitions should already be included.

Step 4: Start Your Project

To launch the development server, run:

npm run dev

Your new Vite project with TypeScript is now running and can be viewed in your browser. After setting up TypeScript, you can start converting your React components to TypeScript by using .tsx file extensions and defining types for your props and state. 

Also Read: State Management Basics in React: A Comprehensive Guide

Basic Hook Types in React

HookDescriptionExample
useStateManages state with primitive types or complex objects/arrays. For nullable types or initializing with null, use useState<Type | null>(null);.const [count, setCount] = useState<number>(0);
useEffectHandles side effects without specific TypeScript annotations.useEffect(() => { console.log(‘Component mounted’); }, []);
useLayoutEffectSimilar to useEffect but synchronously after all DOM mutations.Used for immediate visual updates or measuring DOM elements.
useReducerManages complex state with explicit action types and return types.const [state, dispatch] = useReducer(reducer, initialState);
useCallbackMemoizes functions for preventing unnecessary re-renders.const memoizedCallback = useCallback(() => { doSomething(); }, [dependency]);
useRefPersists values between renders without causing re-renders.const inputRef = useRef<HTMLInputElement>(null);

Setting Up a TypeScript React Component

  • Create a New Component: Inside your React project, create a new file for your component, such as FirstComponent.tsx. Your components will typically reside in a components folder within the src directory of your project.
  • Write Your Component Code: Start by importing React. Then, define your component using either a functional or class-based approach. With TypeScript, you can define interfaces to specify the types of props your component expects. Here’s an example of a simple functional component that displays text:

import React from “react”;

const FirstComponent: React.FC<{}> = () => {

 return <div>Hello, Welcome to React and TypeScript</div>;

};

export default FirstComponent;

  • This component doesn’t receive any props, hence the empty object {} in React.FC<{}>. To render this component, you would import it into your App.tsx and include it in your JSX.
  • Type Props: For components that receive props, you can define an interface to specify the types of these props. For instance:

interface UserProps {

  firstName: string;

  lastName: string;

}

const PropsComponent: React.FC<UserProps> = ({ firstName, lastName }) => {

  return <div>{firstName} {lastName}</div>;

};

This ensures that PropsComponent receives firstName and lastName as strings​.

Typing with Hooks

When using hooks like useState or useEffect in TypeScript, you can provide type annotations to improve code quality and avoid common errors.

For instance, when fetching and displaying a list of users, you could define types for the data you expect to work with and the state structure. Then, you implement a custom hook for fetching the data:

  • Define Your Data Types: Create interfaces to describe your data and state. For a list of users, define a User interface and a UsersState interface to capture the shape of your data and state, respectively.
  • Implement the Custom Hook: Use useState and useEffect to fetch the data from an API and store it in your component’s state. Type annotations help ensure you’re working with the data correctly.
  • Use the Custom Hook: In your component, use the custom hook to fetch and display the users. The TypeScript compiler will check that you’re accessing and using the data according to the types you’ve defined.

// Example of typing with hooks for fetching and displaying users

interface User {

 id: number;

 name: string;

 email: string;

}

const useUsers = (): { users: User[]; loading: boolean } => {

 const [state, setState] = useState<{ users: User[]; loading: boolean }>({ users: [], loading: true });

 // Fetch data and update state here

 return state;

};

function UserList() {

 const { users, loading } = useUsers();

 // Render users or loading state

}

By following these steps, you can leverage TypeScript’s type system to create more reliable and maintainable React components and hooks. This approach not only catches errors early but also makes your code easier to understand and work with.

Also Read: How to Build Your First React Application?

Testing React Components with TypeScript

Testing React components with TypeScript is a straightforward process that ensures your app’s components work as expected. Here’s a simple guide on how to do it:

  • Set Up Your Environment: Before you start, make sure you have a testing library installed. @testing-library/react and jest are popular choices. If you’re using Create React App, jest comes installed out of the box.
  • Install TypeScript Definitions: You might need to install TypeScript definitions for your testing library if they’re not included. For example, you can run npm install @types/jest for jest.
  • Write Your Test: Create a new test file. If your component file is named MyComponent.tsx, your test file could be named MyComponent.test.tsx. In your test file, import the necessary functions from your testing library and the component you want to test.
  • Arrange, Act, and Assert: Follow this pattern in your tests. First, set up your component under test (arrange). Then, perform actions on the component, like simulating user input (act). Finally, check that the component behaves as expected (assert).
  • Run Your Tests: Use your test runner’s command to run the tests. If you’re using jest, the command is usually npm test.
  • Checking Types: TypeScript checks your types at compile time, not at runtime. However, you can use your tests to ensure that your components are receiving the right props and handling them correctly.
  • Mocking and Spies: Sometimes, you’ll need to mock functions or components, especially if they make network requests or interact with a browser API that isn’t available in a test environment. Your testing library and jest provide ways to mock these.
  • Advanced Techniques: As you get more comfortable, you can use more advanced testing techniques like snapshot testing (to capture the rendered output of a component) or writing custom render functions to wrap your components with providers they might depend on (like Redux Store).
  • Continuous Integration: Finally, consider setting up your tests to run automatically on a Continuous Integration (CI) service whenever you push new code. This helps catch errors quickly and ensures that only working code gets merged into your main branch.

Also Read: What is Machine Learning and How Does It Work?

Conclusion

Using TypeScript with React not only improves the developer experience but also leads to the creation of more reliable web applications. By providing static typing, it helps in early detection of errors, making the development process smoother and more efficient. 

The integration of TypeScript into React projects may seem like an additional step, but the long-term benefits in terms of code quality and maintainability are undeniable. 

As we’ve discussed, the key to successfully using TypeScript with React lies in understanding its core principles and applying best practices to your development workflow. Wondering how to make the most as a React developer? Enroll into our Certified React Developer™ certification and turbocharge your career today!

Frequently Asked Questions

What is TypeScript and how does it work with React?

  • TypeScript is a statically typed superset of JavaScript that enhances code reliability and understandability.
  • It works with React by providing static type checking, ensuring that developers catch errors early in the development process.
  • TypeScript helps manage large codebases more effectively and improves the overall developer experience when building React applications.

How do I set up TypeScript with React?

  • For a new project using Create React App, you can initialize it with TypeScript directly by running npx create-react-app my-app –template typescript.
  • For an existing project, install TypeScript and the types for React and ReactDOM using npm install –save typescript @types/react @types/react-dom.
  • Rename your file extensions from .js to .tsx for files with JSX or .ts for files without JSX to indicate TypeScript usage.

What are some basic TypeScript types commonly used in React?

  • String, Number, Boolean, Array, and Object types are frequently used for defining props and state in React components.
  • TypeScript also supports optional props using the ? syntax, allowing for flexibility in component usage.
  • Function types, including those with parameters and return types, are essential for defining callback functions and event handlers in React.

How can I test React components with TypeScript?

  • Set up your testing environment with libraries like @testing-library/react and jest, commonly used for React testing.
  • Write tests in files named with the .test.tsx extension, importing necessary functions from your testing library and the component to be tested.
  • Use techniques like arranging, acting, and asserting to ensure your components behave as expected during testing.
  • Leverage TypeScript’s type checking capabilities to verify that components receive correct props and handle them appropriately in your tests.