TypeScript Course
TypeScript
/
Beginner

React: Typing State

Definition

Providing type parameters to the `useState` and `useReducer` hooks to enforce the type of data stored in React state.

Explain Like I'm New

Usually, TS is smart enough to guess your state. If you write `useState(0)`, TS knows the state is a number. But what if the state starts out empty, like `useState()`? TS has no idea what will go in there later. You must tell it: 'This empty state will eventually hold an Array of Users' using Generics.

Real World Example

Fetching a user profile. The initial state is `null` because the data hasn't loaded yet. You type it as `const [user, setUser] = useState<User | null>(null);`.

Common Use Cases

  • •Complex state objects
  • •State that starts as null/undefined
  • •useReducer actions

Interactive Example

import { useState } from 'react';

interface User {
  id: number;
  name: string;
}

export function Profile() {
  // 1. INFERENCE (Good for primitives)
  const [isLoading, setIsLoading] = useState(false); // Inferred as boolean

  // 2. EXPLICIT GENERICS (Required for null/undefined starts)
  const [user, setUser] = useState<User | null>(null);

  // 3. EXPLICIT ARRAYS (Required for empty arrays)
  const [followers, setFollowers] = useState<User[]>([]);

  const handleLoad = () => {
    setUser({ id: 1, name: "Alice" }); // TS guarantees this matches the interface
  };

  return <div>{user ? user.name : "Loading..."}</div>;
}

Interview Questions

basic

  • Do you always need to type `useState` explicitly?

intermediate

  • How do you type `useState` for an array of objects that starts empty?

advanced

  • How do you type the Action object in `useReducer`?

Flash Cards

Question

Do you always need to type it?

Click to reveal answer
Answer

No! Rely on inference for primitives. `useState(false)` is perfectly inferred as a boolean. Only add `<Type>` when inference fails or the state starts as null.

Question

How to type an empty array?

Click to reveal answer
Answer

`const [items, setItems] = useState<Item[]>([]);`. If you don't provide `<Item[]>`, TS infers it as `never[]`, meaning it will NEVER let you push anything into that array!