TypeScript with React

TypeScript adds static types to JavaScript so mistakes are caught while you write code, not when a user hits a bug. In React, that means typing your props , state , and event handlers — the editor autocompletes them and the compiler refuses to ship a wrong shape. By the end you'll type a component end to end and read the most common React+TS patterns with confidence.

Learn TypeScript with React in our free React course — a beginner-friendly interactive lesson with runnable examples, a practice exercise and a quick recall.

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

1️⃣ Typing Props

The single most valuable thing TypeScript does for React: describe the shape of a component's props. Declare a type (or interface ) and annotate the props parameter. Now every place that renders the component is checked — pass the wrong type or forget a required prop and you get a red squiggle immediately.

The demo runs a typed function so you can see required and optional fields in action (the types are real TS in the block above):

Your turn — fill in the type annotations so only valid data is accepted:

2️⃣ Typing State

Most of the time TypeScript infers state from the initial value: useState(0) is a number , useState("") is a string . You only annotate when the initial value doesn't tell the whole story — like null at first, or a union of options.

Union types shine for status flags and variants — the demo shows a Status union that makes typos impossible:

3️⃣ Events & Children

Two patterns you'll use constantly. Type an event handler with React's built-in event types so e.target.value is known. Type children with React.ReactNode — the catch-all for anything renderable.

A handy rule: for a value that returns nothing, type it ; for anything you can render, reach for React.ReactNode .

These lines declare a typed component. Put them in a correct order:

1) What does the ? in disabled?: boolean mean?

The prop is optional — it may be omitted. Inside the component its type is boolean | undefined .

No. TypeScript infers number from the initial value. Annotate only for null starts or unions, e.g. .

3) Which type covers "anything renderable" for the children prop?

React.ReactNode — it covers JSX, strings, numbers, arrays, null, and more.

📋 Quick Reference

Write a typed function that formats a badge. Type count as a number and an optional tone union, then return a label. Predict the output for the calls below.

Practice quiz

How do you type a component's props in modern React + TypeScript?

  • Add PropTypes at the bottom of the file
  • Wrap the component in a generic
  • Define a type or interface for the props and annotate the props parameter
  • Props can't be typed

Answer: Define a type or interface for the props and annotate the props parameter. Declare a type/interface (e.g. ButtonProps) and annotate the parameter: function Button(props: ButtonProps). Every usage is then checked.

What does the ? in disabled?: boolean mean?

  • The prop is optional — it may be omitted, and its type becomes boolean | undefined
  • The prop is private
  • The prop defaults to true
  • The prop is nullable but required

Answer: The prop is optional — it may be omitted, and its type becomes boolean | undefined. A ? marks the prop optional. Callers may omit it, and inside the component its type includes undefined.

Does useState(0) need an explicit type annotation?

  • Yes, always annotate useState
  • Only in strict mode
  • Yes, or it defaults to any
  • No — TypeScript infers number from the initial value

Answer: No — TypeScript infers number from the initial value. Inference handles primitives: useState(0) is number, useState('') is string. You annotate only when the initial value doesn't tell the whole story.

When do you need to annotate useState with a generic?

  • Never
  • When the initial value is null or you need a union type, e.g. useState<User | null>(null)
  • Only for numbers
  • Whenever the state is an object

Answer: When the initial value is null or you need a union type, e.g. useState<User | null>(null). A null start or a union of options can't be inferred fully, so you supply the generic: useState<User | null>(null) or useState<'idle' | 'done'>('idle').

What is a good use for union types like 'idle' | 'loading' | 'success'?

  • Constraining a status to a fixed set of exact strings so typos become compile errors
  • Counting renders
  • Replacing useState
  • Typing event handlers

Answer: Constraining a status to a fixed set of exact strings so typos become compile errors. A literal union restricts a value to specific strings. Mistyping 'lodaing' won't compile, catching the bug before runtime.

How should you type the children prop?

  • string
  • any
  • React.ReactNode
  • JSX.Element only

Answer: React.ReactNode. React.ReactNode is the catch-all for anything renderable: JSX, strings, numbers, arrays, null, and more.

How do you type an input's change handler so e.target.value is known?

  • (e: any) => void
  • (e: React.ChangeEvent<HTMLInputElement>) => void
  • (e: Event) => void
  • (e: string) => void

Answer: (e: React.ChangeEvent<HTMLInputElement>) => void. React's built-in event types describe the event. React.ChangeEvent<HTMLInputElement> makes e.target.value a known string.

What type best describes a callback prop that returns nothing, like onClick?

  • () => null
  • Function
  • () => undefined required
  • () => void

Answer: () => void. () => void types a function that takes no arguments and returns nothing — the standard shape for event-style callbacks.

Is React.FC the recommended way to type a component today?

  • Yes, always use React.FC
  • Not really — annotating the props object directly is the recommended modern style; React.FC adds quirks
  • React.FC is required for hooks
  • React.FC is the only option in strict mode

Answer: Not really — annotating the props object directly is the recommended modern style; React.FC adds quirks. Many teams skip React.FC because it adds an implicit children prop and some quirks. Annotating props directly (function Comp(props: Props)) is preferred.

You get "Property 'onClick' is missing in type". What does it mean?

  • onClick is misspelled in React
  • TypeScript is broken
  • You forgot a required prop when rendering the component — add it or mark it optional with ?
  • onClick must be a string

Answer: You forgot a required prop when rendering the component — add it or mark it optional with ?. The error flags a missing required prop. Either pass it, or mark it optional with ? if it genuinely is.