React with TypeScript: A Practical Getting Started Guide

TypeScript adds a type system to React. Learn how to create a typed React project and type props, state, and event handlers.

5 min read

This guide shows how to use React with TypeScript, from a fresh project to typed props, state, and event handlers. TypeScript catches type mistakes before they reach the browser, and React's type definitions describe components and hooks out of the box.

The examples use TSX, the TypeScript version of JSX. If you know React but not TypeScript, the ideas map one to one: you add types without changing the component model. A later article covers how to type React props with TypeScript in depth.

Create a TypeScript React project

The fastest start is the Vite TypeScript template, which adds a TypeScript compiler and type definitions on top of the React template. Run the scaffold command:

bashbash
npm create vite@latest my-app -- --template react-ts

The command creates a folder named my-app. Open it in your editor.

Files that contain JSX use the .tsx extension, and the template already includes the tsconfig files with the settings React needs. The build script runs tsc before Vite builds, so type errors stop the build.

If you prefer the plain JavaScript version first, the guide on creating a React app with Vite shows that path.

Type a component's props

Props are typed with an interface or an inline type. An interface reads well for a component with a few fields:

App.tsxApp.tsx
interface GreetingProps {
  name: string;
}
 
function Greeting({ name }: GreetingProps) {
  return <h1>Hello, {name}</h1>;
}

If you pass a number to Greeting, the editor underlines it before you save. The type reports the mistake at write time instead of runtime, so it never reaches the browser.

Type state

useState infers the type from the initial value. A number stays a number, so setCount rejects anything else:

App.tsxApp.tsx
import { useState } from "react";
 
function Counter() {
  const [count, setCount] = useState(0);
 
  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}

When a value can be one of several strings, the allowed values need to be explicit. Pass a type argument to useState inside the component to lock the union:

App.tsxApp.tsx
type Status = "idle" | "loading" | "ready";
 
const [status, setStatus] = useState<Status>("idle");

Now setStatus only accepts those three strings.

Type event handlers

Events in React are typed with React.ChangeEvent and similar types from @types/react. The handler parameter needs the matching element type:

App.tsxApp.tsx
import { useState } from "react";
 
function Search() {
  const [query, setQuery] = useState("");
  function handleChange(event: React.ChangeEvent<HTMLInputElement>) {
    setQuery(event.target.value);
  }
  return <input value={query} onChange={handleChange} aria-label="Search" />;
}

The input updates query as you type, and the handler is fully typed. TypeScript knows event.target is the input element, so value is a string.

The aria-label gives the field an accessible name because it has no visible label beside it. The controlled input pattern itself is the same as the JavaScript version, with types added.

What to learn next

Type a few components in your own project and watch the editor catch mistakes before you save. As the project grows, the editor becomes a faster checker than the browser console, and type errors point at the exact file and line. Then read the props guide to cover optional fields, union props, and the children prop.

Rune AI

Rune AI

Key Insights

  • Create a typed project with npm create vite@latest my-app -- --template react-ts.
  • Use .tsx for files that contain JSX.
  • Type props with an interface or inline type.
  • useState infers types, or accepts an explicit type argument.
  • Type events with React.ChangeEvent and the matching element type.
RunePowered by Rune AI

Frequently Asked Questions

Is TypeScript required for React?

No. React works with plain JavaScript, and TypeScript is optional. It adds a type system that catches mistakes before the browser runs the code.

What file extension do React TypeScript files use?

Files that contain JSX use the .tsx extension. Plain TypeScript files without JSX use .ts.

Do I need @types/react for a TypeScript React project?

Yes. @types/react and @types/react-dom provide the TypeScript definitions for React. The Vite TypeScript template includes them automatically.

Conclusion

TypeScript adds static types to React without changing the component model. Create a project from the react-ts template, type props with an interface, let useState infer or set explicit types, and type events with React.ChangeEvent.