MindForge
MindForge
DashboardHelp & Support
Dashboard
MindForge

Interview Preparation Bootcamp

Course progress

0%
0 of 177 modules complete
Start Here0/1
  • How to Use This Course
Data Structures & Algorithms0/27
  • Arrays and Hashing
  • Two Pointers
  • Sliding Window
  • Sliding Window: Harder Problems
  • Binary Search
  • Stacks
  • Practice Test: Arrays, Pointers, Windows, Search and Stacks
  • Trees: Traversals and Core Patterns
  • Binary Search Trees and Rebuilding a Tree
  • Tries (Prefix Trees)
  • Heaps and Priority Queues
  • Graphs: BFS and DFS
  • Topological Sort and Cycle Detection
  • Union-Find (Disjoint Set Union)
  • Practice Test: Trees, Heaps and Graphs
  • Dynamic Programming Basics
  • Dynamic Programming: Two Dimensions
  • Dynamic Programming: Hard String Matching
  • Backtracking
  • Backtracking: Constraint Satisfaction
  • Greedy Algorithms
  • Interval Problems
  • Bit Manipulation
  • Math and Geometry
  • String Manipulation
  • Pattern Recall and Mock Coding Rounds
  • Practice Test: DP, Backtracking, Greedy and More

System Design

Foundations0/16
  • The System Design Interview Framework
  • Back-of-the-Envelope Estimation
  • Networking and Protocols for Design
  • API Design and Idempotency
  • Load Balancing, Proxies, and Scaling Out
  • Caching and CDNs
  • Choosing a Database: Storage, Indexes and Transactions
  • Replication, Partitioning, and Sharding
  • CAP, PACELC, and Levels of Consistency
  • Messaging, Queues, and Event-Driven Architecture
  • Distributed Transactions and Data Integrity
  • Coordination, Consensus, and Distributed Locks
  • Reliability, Resilience, and Rate Limiting
  • Observability, Security, and Cost
  • System Design Cheat Sheet
  • Practice Test: System Design Foundations
Case Studies0/23
  • Design a URL Shortener
  • Design a Rate Limiter
  • Design a Notification Service
  • Design a Job Queue System
  • Design a Chat App (WhatsApp)
  • Design an Analytics Pipeline
  • Design a Multi-tenant SaaS Architecture
  • Design a Social Media Feed (Twitter/X)
  • Design a Search Autocomplete System
  • Design a File Storage Service (Dropbox)
  • Design Google Docs
  • Design a Code Review System
  • Design Netflix
  • Design YouTube
  • Design Spotify
  • Design Uber/Lyft
  • Design Airbnb
  • Design Ticketmaster (Eventbrite)
  • Design an E-commerce Cart, Checkout, and Catalog
  • Design a Payment System
  • Design a Logging and Monitoring System
  • Mock Design Rounds
  • Practice Test: System Design Case Studies
Low-Level Design0/19
  • The LLD Interview Framework and UML
  • OOP Foundations for Design
  • SOLID Principles
  • Creational Patterns
  • Structural Patterns
  • Behavioral Patterns I — Strategy, Observer, Command, State, Template Method
  • Behavioral Patterns II and Anti-Patterns
  • Concurrency in Low-Level Design
  • Design a Parking Lot
  • Design an Elevator System
  • Design a Movie Ticket Booking System
  • Design an Expense-Sharing App (Splitwise)
  • Design a Vending Machine and an ATM
  • Design a Rate Limiter and a Logging Framework
  • Design a Notification Service and an In-Memory Cache
  • Design Games — Tic-Tac-Toe, Snake and Ladder, Chess
  • Database Design for LLD
  • LLD Cheat Sheet and Recall Drill
  • Practice Test: Low-Level Design

Backend

Python0/5
  • How Python Runs Your Code
  • Functions Deep Dive: Closures, Generators, Context Managers, Scope
  • Classes Deep Dive: Method Types, MRO, Metaclasses
  • Standard Library and Serialization
  • Practice Test: Python
Django0/6
  • Django Request Lifecycle
  • Lab: Django Middleware — Request ID & Response Time
  • Django ORM and Querysets
  • Django's Cache Framework
  • Practice Test: Django
  • Django in Production: Debugging Labs
FastAPI0/5
  • FastAPI, ASGI, and Async
  • FastAPI Dependency Injection
  • FastAPI Background Tasks
  • Lab: FastAPI Async — Concurrent Aggregation
  • Practice Test: FastAPI
Databases (PostgreSQL)0/6
  • Indexing
  • Query Optimization
  • Transactions and Isolation
  • Migrations and Schema Changes
  • Hierarchical Data and Safe Concurrent Updates
  • Practice Test: Databases
Caching, Queues & Distributed Systems0/8
  • Redis Caching
  • Redis Advanced Patterns
  • Celery and Background Workers
  • Kafka and Message Queues
  • Async Pipelines
  • Distributed Systems Basics
  • Distributed Locks
  • Practice Test: Caching, Queues and Distributed Systems
APIs, Security & Deployment0/9
  • REST API Design
  • API Versioning and Error Handling
  • API Security and Authentication
  • WebSockets and Real-Time Systems
  • Docker and Containers
  • File Storage with S3
  • Testing Strategies
  • Mock Backend Round
  • Practice Test: APIs, Security and Deployment
Frontend0/38
  • HTML Document Structure and Semantics
  • CSS Box Model, Flexbox and Grid
  • CSS Architecture and Theming
  • CSS and Rendering Performance
  • Variables, Scope, Hoisting, and Truthiness
  • Functions, this, and Binding
  • Objects and Prototypal Inheritance
  • JavaScript Utility Patterns: Cloning, Caching, and Memory
  • Promises From Scratch
  • The Event Loop and Browser Rendering Pipeline
  • The DOM: Nodes, Events, and Traversal
  • Practice Test: HTML, CSS and JavaScript
  • React Rendering Fundamentals
  • React Hooks Internals
  • React Performance
  • Lab: React — Stateful Counter Component
  • State Management
  • State Machines in React
  • React Custom Hooks and Composition Patterns
  • TypeScript for React
  • React Testing
  • Practice Test: React
  • HTTP and Caching
  • Network Performance and Web Vitals
  • Code Splitting and Bundles
  • Virtualization
  • GraphQL and Data Fetching
  • Web Security
  • WebSockets and Real-time
  • SSR and Next.js
  • Micro-frontends
  • Build Tools and Bundling
  • Accessibility
  • Error Handling
  • Internationalization
  • Animation
  • Rapid Recall and Mock Frontend Rounds
  • Practice Test: Performance, Architecture and Production
Behavioral & Interview Day0/14
  • Resume and Project Walkthroughs
  • The STAR Method and Refining Your Stories
  • Conflict and Difficult Coworkers
  • Failures, Incidents, and Obstacles
  • Leadership, Mentorship, and Ownership
  • Teamwork, Communication, and Feedback
  • Growth and Handling Ambiguity
  • Career Goals, Why This Company, and Negotiation
  • Situational Questions
  • Company Research
  • Mock Behavioral Rounds
  • Interview Day
  • After the Interview
  • Practice Test: Behavioral and Interview Day
TypeScript for React
Course contents

Interview Preparation Bootcamp

Course progress

0%
0 of 177 modules complete
Start Here0/1
  • How to Use This Course
Data Structures & Algorithms0/27
  • Arrays and Hashing
  • Two Pointers
  • Sliding Window
  • Sliding Window: Harder Problems
  • Binary Search
  • Stacks
  • Practice Test: Arrays, Pointers, Windows, Search and Stacks
  • Trees: Traversals and Core Patterns
  • Binary Search Trees and Rebuilding a Tree
  • Tries (Prefix Trees)
  • Heaps and Priority Queues
  • Graphs: BFS and DFS
  • Topological Sort and Cycle Detection
  • Union-Find (Disjoint Set Union)
  • Practice Test: Trees, Heaps and Graphs
  • Dynamic Programming Basics
  • Dynamic Programming: Two Dimensions
  • Dynamic Programming: Hard String Matching
  • Backtracking
  • Backtracking: Constraint Satisfaction
  • Greedy Algorithms
  • Interval Problems
  • Bit Manipulation
  • Math and Geometry
  • String Manipulation
  • Pattern Recall and Mock Coding Rounds
  • Practice Test: DP, Backtracking, Greedy and More

System Design

Foundations0/16
  • The System Design Interview Framework
  • Back-of-the-Envelope Estimation
  • Networking and Protocols for Design
  • API Design and Idempotency
  • Load Balancing, Proxies, and Scaling Out
  • Caching and CDNs
  • Choosing a Database: Storage, Indexes and Transactions
  • Replication, Partitioning, and Sharding
  • CAP, PACELC, and Levels of Consistency
  • Messaging, Queues, and Event-Driven Architecture
  • Distributed Transactions and Data Integrity
  • Coordination, Consensus, and Distributed Locks
  • Reliability, Resilience, and Rate Limiting
  • Observability, Security, and Cost
  • System Design Cheat Sheet
  • Practice Test: System Design Foundations
Case Studies0/23
  • Design a URL Shortener
  • Design a Rate Limiter
  • Design a Notification Service
  • Design a Job Queue System
  • Design a Chat App (WhatsApp)
  • Design an Analytics Pipeline
  • Design a Multi-tenant SaaS Architecture
  • Design a Social Media Feed (Twitter/X)
  • Design a Search Autocomplete System
  • Design a File Storage Service (Dropbox)
  • Design Google Docs
  • Design a Code Review System
  • Design Netflix
  • Design YouTube
  • Design Spotify
  • Design Uber/Lyft
  • Design Airbnb
  • Design Ticketmaster (Eventbrite)
  • Design an E-commerce Cart, Checkout, and Catalog
  • Design a Payment System
  • Design a Logging and Monitoring System
  • Mock Design Rounds
  • Practice Test: System Design Case Studies
Low-Level Design0/19
  • The LLD Interview Framework and UML
  • OOP Foundations for Design
  • SOLID Principles
  • Creational Patterns
  • Structural Patterns
  • Behavioral Patterns I — Strategy, Observer, Command, State, Template Method
  • Behavioral Patterns II and Anti-Patterns
  • Concurrency in Low-Level Design
  • Design a Parking Lot
  • Design an Elevator System
  • Design a Movie Ticket Booking System
  • Design an Expense-Sharing App (Splitwise)
  • Design a Vending Machine and an ATM
  • Design a Rate Limiter and a Logging Framework
  • Design a Notification Service and an In-Memory Cache
  • Design Games — Tic-Tac-Toe, Snake and Ladder, Chess
  • Database Design for LLD
  • LLD Cheat Sheet and Recall Drill
  • Practice Test: Low-Level Design

Backend

Python0/5
  • How Python Runs Your Code
  • Functions Deep Dive: Closures, Generators, Context Managers, Scope
  • Classes Deep Dive: Method Types, MRO, Metaclasses
  • Standard Library and Serialization
  • Practice Test: Python
Django0/6
  • Django Request Lifecycle
  • Lab: Django Middleware — Request ID & Response Time
  • Django ORM and Querysets
  • Django's Cache Framework
  • Practice Test: Django
  • Django in Production: Debugging Labs
FastAPI0/5
  • FastAPI, ASGI, and Async
  • FastAPI Dependency Injection
  • FastAPI Background Tasks
  • Lab: FastAPI Async — Concurrent Aggregation
  • Practice Test: FastAPI
Databases (PostgreSQL)0/6
  • Indexing
  • Query Optimization
  • Transactions and Isolation
  • Migrations and Schema Changes
  • Hierarchical Data and Safe Concurrent Updates
  • Practice Test: Databases
Caching, Queues & Distributed Systems0/8
  • Redis Caching
  • Redis Advanced Patterns
  • Celery and Background Workers
  • Kafka and Message Queues
  • Async Pipelines
  • Distributed Systems Basics
  • Distributed Locks
  • Practice Test: Caching, Queues and Distributed Systems
APIs, Security & Deployment0/9
  • REST API Design
  • API Versioning and Error Handling
  • API Security and Authentication
  • WebSockets and Real-Time Systems
  • Docker and Containers
  • File Storage with S3
  • Testing Strategies
  • Mock Backend Round
  • Practice Test: APIs, Security and Deployment
Frontend0/38
  • HTML Document Structure and Semantics
  • CSS Box Model, Flexbox and Grid
  • CSS Architecture and Theming
  • CSS and Rendering Performance
  • Variables, Scope, Hoisting, and Truthiness
  • Functions, this, and Binding
  • Objects and Prototypal Inheritance
  • JavaScript Utility Patterns: Cloning, Caching, and Memory
  • Promises From Scratch
  • The Event Loop and Browser Rendering Pipeline
  • The DOM: Nodes, Events, and Traversal
  • Practice Test: HTML, CSS and JavaScript
  • React Rendering Fundamentals
  • React Hooks Internals
  • React Performance
  • Lab: React — Stateful Counter Component
  • State Management
  • State Machines in React
  • React Custom Hooks and Composition Patterns
  • TypeScript for React
  • React Testing
  • Practice Test: React
  • HTTP and Caching
  • Network Performance and Web Vitals
  • Code Splitting and Bundles
  • Virtualization
  • GraphQL and Data Fetching
  • Web Security
  • WebSockets and Real-time
  • SSR and Next.js
  • Micro-frontends
  • Build Tools and Bundling
  • Accessibility
  • Error Handling
  • Internationalization
  • Animation
  • Rapid Recall and Mock Frontend Rounds
  • Practice Test: Performance, Architecture and Production
Behavioral & Interview Day0/14
  • Resume and Project Walkthroughs
  • The STAR Method and Refining Your Stories
  • Conflict and Difficult Coworkers
  • Failures, Incidents, and Obstacles
  • Leadership, Mentorship, and Ownership
  • Teamwork, Communication, and Feedback
  • Growth and Handling Ambiguity
  • Career Goals, Why This Company, and Negotiation
  • Situational Questions
  • Company Research
  • Mock Behavioral Rounds
  • Interview Day
  • After the Interview
  • Practice Test: Behavioral and Interview Day
Browsing without an account — progress is saved in this browser only.Sign in to save it

TypeScript for React

Reading30 min

Most production React codebases are TypeScript now, and interviewers routinely ask you to type a component, a hook, or an API response live. This lesson covers the patterns that come up constantly: typing props and generics, the utility types you'll reach for weekly, event handler types, and building a type-safe boundary around whatever fetch actually hands you.

Typing props

tsx
interface ButtonProps {
  label: string;
  onClick: () => void;
  variant?: "primary" | "secondary" | "danger"; // a union, not a bare string
  children?: React.ReactNode;
}

function Button({ label, onClick, variant = "primary", children }: ButtonProps) {
  return <button className={`btn btn-${variant}`} onClick={onClick}>{children ?? label}</button>;
}

interface versus type for props is a style convention more than a hard rule, interface is extendable and gives slightly better error messages, both work fine, and interviewers care more that you're consistent than which one you pick. React.ReactNode versus React.ReactElement is a genuine trip-up: ReactNode covers anything renderable, elements, strings, numbers, arrays, null, booleans, use it for children. ReactElement is specifically the result of <Foo /> or React.createElement, reach for it only when you need to clone or inspect an actual element via React.cloneElement, not for general children.

Remember: use ReactNode for children. Reach for ReactElement only when you specifically need to clone or inspect a real element.

Sign in to try this knowledge check.

Generic components

A generic component lets the caller determine a type parameter, staying reusable without falling back to any.

tsx
interface SelectProps<T> {
  items: T[]; value: T; onChange: (value: T) => void; getLabel: (item: T) => string; getKey: (item: T) => string | number;
}
function Select<T>({ items, value, onChange, getLabel, getKey }: SelectProps<T>) {
  return (
    <select value={getKey(value)} onChange={(e) => { const selected = items.find(i => String(getKey(i)) === e.target.value); if (selected) onChange(selected); }}>
      {items.map(item => <option key={getKey(item)} value={getKey(item)}>{getLabel(item)}</option>)}
    </select>
  );
}

// Usage — T is inferred as User, no explicit type argument needed
function UserPicker({ users, selected, onSelect }: { users: User[]; selected: User; onSelect: (u: User) => void }) {
  return <Select items={users} value={selected} onChange={onSelect} getLabel={u => u.name} getKey={u => u.id} />;
}

One syntax detail worth knowing cold: a generic arrow-function component in a .tsx file needs a trailing comma, <T,>, or an extends unknown constraint, so the parser doesn't mistake the type parameter for the start of a JSX tag. A function declaration doesn't have that ambiguity:

tsx
const List = <T,>({ items }: { items: T[] }) => <ul>{items.map((i, idx) => <li key={idx}>{String(i)}</li>)}</ul>;
function List2<T>({ items }: { items: T[] }) { return <ul>{items.map((i, idx) => <li key={idx}>{String(i)}</li>)}</ul>; }

Remember: a generic arrow-function component in a .tsx file needs the trailing comma, <T,>, or the parser reads <T> as the start of a JSX tag.

Sign in to try this knowledge check.

Utility types worth having ready

ts
interface Product { id: string; name: string; price: number; description: string; inStock: boolean; }

function updateProduct(id: string, changes: Partial<Product>) {} // every field optional — patch payloads
updateProduct("p1", { price: 29.99 }); // no need to pass every field

interface DraftProduct extends Partial<Product> {}
function publishProduct(draft: Required<DraftProduct>) {} // every field mandatory, even ones declared optional on the source type

type ProductSummary = Pick<Product, "id" | "name" | "price">;    // a narrow subset
type ProductWithoutDescription = Omit<Product, "description">;    // everything except listed fields
type ProductsById = Record<string, Product>;                      // a typed dictionary

function renderProduct(p: Readonly<Product>) { /* p.price = 0; // error */ } // an immutable view
Utility What it does Typical use
Partial<T> All props optional Patch/update payloads, form state before submit
Required<T> All props mandatory Validating a fully-filled form
Pick<T, K> Keep only listed keys Narrow view models, list-row data
Omit<T, K> Drop listed keys Removing sensitive or internal fields
Record<K, V> Typed key-value map Lookup tables, Record<UserId, User>
Readonly<T> All props immutable Props that must never be mutated in place

Remember: Partial<T> for patch payloads, Pick/Omit for narrow views, Record for typed lookup tables. Reach for these before writing a new interface from scratch.

Sign in to try this knowledge check.

Typing event handlers correctly

React's synthetic events are specific to the element and event kind. Typing a handler as plain Event loses everything you actually need, like target.value.

tsx
function SearchForm() {
  const [query, setQuery] = useState("");
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => setQuery(e.target.value);
  const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => { e.preventDefault(); };
  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => { if (e.key === "Enter") {} };
  const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => { console.log("clicked at", e.clientX, e.clientY); };
  return <form onSubmit={handleSubmit}><input value={query} onChange={handleChange} onKeyDown={handleKeyDown} /><button type="submit" onClick={handleClick}>Search</button></form>;
}

The generic parameter, HTMLInputElement, HTMLFormElement, matters because it's what correctly types e.currentTarget. Typing every handler as React.ChangeEvent<HTMLElement> loses .value on non-input elements and produces confusing errors further down the line, the specific type argument is what makes the whole thing worth doing at all.

Remember: the generic parameter on a React event type, <HTMLInputElement>, is what gives you a correctly typed .value on e.target.

Sign in to try this knowledge check.

A type-safe boundary around fetch

The goal is to never let any leak in from the network, and to fail loudly with a typed error instead of silently passing malformed data downstream.

ts
type ApiResult<T> = { ok: true; data: T } | { ok: false; error: string; status: number };

async function apiGet<T>(path: string): Promise<ApiResult<T>> {
  try {
    const res = await fetch(path);
    if (!res.ok) return { ok: false, error: await res.text(), status: res.status };
    return { ok: true, data: (await res.json()) as T }; // trust boundary — see below
  } catch (err) {
    return { ok: false, error: err instanceof Error ? err.message : "Unknown error", status: 0 };
  }
}

async function loadUser(id: string) {
  const result = await apiGet<User>(`/api/users/${id}`);
  if (!result.ok) { console.error(result.error, result.status); return null; }
  return result.data; // narrowed to User here, the ok: true branch
}

as T after res.json() is a type assertion, not runtime validation, TypeScript trusts you, but the network can send anything at all. For a real trust boundary, user input, a third-party API, validate at runtime with a schema library and derive the TypeScript type from the schema itself, so the two can never drift apart:

ts
import { z } from "zod";
const UserSchema = z.object({ id: z.string(), name: z.string() });
type User = z.infer<typeof UserSchema>;

async function loadUser(id: string): Promise<User> {
  const res = await fetch(`/api/users/${id}`);
  return UserSchema.parse(await res.json()); // throws on a shape mismatch — no silent `any` slipping through
}

Remember: as T is a promise to the compiler, not a runtime check. A schema library like Zod validates the shape for real and derives the type from the same source.

Sign in to try this knowledge check.

Discriminated unions: the pattern worth remembering above everything else here

Model mutually exclusive states as a union rather than several independent booleans, so impossible states, loading: true and error: "x" at once, simply can't be represented in the type at all.

tsx
type FetchState<T> = { status: "idle" } | { status: "loading" } | { status: "success"; data: T } | { status: "error"; error: string };

function useFetch<T>(url: string) {
  const [state, setState] = useState<FetchState<T>>({ status: "idle" });
  useEffect(() => {
    setState({ status: "loading" });
    fetch(url).then(res => res.json()).then((data: T) => setState({ status: "success", data })).catch(err => setState({ status: "error", error: String(err) }));
  }, [url]);
  return state;
}

function UserProfile({ url }: { url: string }) {
  const state = useFetch<User>(url);
  switch (state.status) {
    case "idle": case "loading": return <Spinner />;
    case "error": return <ErrorMessage text={state.error} />; // state.error only exists in this branch
    case "success": return <div>{state.data.name}</div>;       // state.data only exists in this branch
  }
}

TypeScript narrows state inside each case based on the status literal, which is exactly why autocomplete offers .error only in the error branch and .data only in the success branch, and why the compiler refuses to let you read state.data anywhere it might not exist. If one pattern from this lesson is worth carrying forward above the rest, it's this one: it shows up constantly in live-coding rounds because it's a compact, precise way to prove you think about state shape before you think about JSX.

Remember: a discriminated union makes the compiler refuse to let you read a field, like state.data, anywhere it isn't guaranteed to exist.

Sign in to try this knowledge check.
PreviousReact Custom Hooks and Composition PatternsNextReact Testing

Course progress

0%
0 of 177 modules complete

On this page

  • Typing props
  • Generic components
  • Utility types worth having ready
  • Typing event handlers correctly
  • A type-safe boundary around fetch
  • Discriminated unions: the pattern worth remembering above everything else here