React

By the end of this lesson you'll be able to type a React component's props, its useState and useRef , and its event handlers — so your editor catches mistakes as you type instead of your users finding them at runtime.

Learn Python, JavaScript, Java and more with free interactive lessons, real projects and AI-powered help. Beginner-friendly.

Part of the free TypeScript course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

A component's props interface is the label on a shipping box : "Contains: 1 string (name), 1 number (age), optional VIP sticker." Anyone sending you a box must match that label, or the post office rejects it at the counter — before it ships. Plain React lets any box through and you discover the missing parts after delivery (at runtime). TypeScript checks the label at the counter, so wrong or missing props never reach your users.

1. Typing Component Props

Every React component receives a single props object. To type it, you describe its shape once with an interface , then annotate the parameter with that interface. From then on TypeScript enforces required props, rejects wrong types, and autocompletes prop names for you. A ? after a prop name makes it optional. Read this worked example carefully.

You can describe props with either an interface or a type alias — for prop shapes they're nearly identical. A common convention: use interface for object shapes you might extend, and type for unions and one-offs. Notice the union — that prop can only be one of those two strings.

Fill in each ___ below. This snippet is read-only — work it out in your head (or type it into a real .tsx file) and check against the comments.

2. Typing useState & useRef

Both hooks are generic — they take a type inside angle brackets, like . Most of the time you don't need to write it: useState(0) is inferred as a number from its initial value. You add an explicit when the initial value can't describe the real type — an empty array, or a value that's null now but will hold an object later.

Write and TypeScript infers the type as never[] — "an array that can hold nothing." The moment you call you get "Argument of type string is not assignable to parameter of type never."

The fix is to tell it what the array holds: . This is the single most common state-typing mistake.

Replace each ___ with the correct generic. Check yourself against the lines.

3. Typing Events & Children

React gives each event a specific type, and you tell it which HTML element fired it using a generic. Type a change handler as and e.target.value is correctly known to be a string. A click handler is . To accept nested content (anything between your component's tags), type the children prop as React.ReactNode — the catch-all for "anything renderable."

4. Run It: the immutable state-update pattern

The TSX above can't run in this editor, but the update pattern you'll use with a typed is plain JavaScript. The golden rule: never mutate the existing state — build and return a brand-new value . This runnable demo simulates setTodos with a function so you can press Run and watch it work.

You'll meet React.FC (short for "Function Component") in older code and tutorials. It works, but most teams have moved away from it in favour of typing the props directly on a plain function.

For props they're almost interchangeable. A common convention: interface for object/prop shapes (it can be extended later), and type for unions, intersections, and one-offs. Pick one style and stay consistent within a project.

Q: Do I always have to write the generic on useState ?

No — TypeScript infers it from the initial value, so useState(0) is a number automatically. Add the explicit only when the initial value can't describe the real type: empty arrays ( ) and nullable values ( ).

Because the event wasn't typed to a specific element. A plain Event has no value . Type the handler and TypeScript knows e.target is an input, so .value appears.

Not wrong — just out of fashion. It used to silently add a children prop and makes generic components awkward. The React docs now show plain functions with directly-typed props, so prefer unless your codebase already standardises on FC .

No blanks this time — just a brief and an outline. Build it in a real react-ts project, then use the self-check at the bottom to confirm your types are right.

Practice quiz

How do you type a React component's props with an interface?

  • Annotate the props parameter: function C(props: Props)
  • Wrap the function in Props<>
  • Pass Props to useState
  • Props are inferred from JSX automatically

Answer: Annotate the props parameter: function C(props: Props). Describe the shape once with an interface, then annotate the single props parameter with it.

What does a '?' after a prop name mean in a props interface?

  • The prop is private
  • The prop is optional
  • The prop is readonly
  • The prop is a boolean

Answer: The prop is optional. isVip?: boolean makes the prop optional, so callers may omit it.

Why does 'const [items, setItems] = useState([])' cause trouble?

  • It throws at runtime