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.