A generic List and a generic Select
The script picks free in the select. onChange={setPlan} type-checks because Select inferred T = "all" | "free" | "pro" from PLANS, which exactly matches the state's setter. The same List renders Users and strings, and each use knows its own item type.
Generic components (List<T>, Select<T>) keep the caller's item type all the way into callbacks; a polymorphic as prop lets one component render any element with that element's props; discriminated union props make invalid prop combinations impossible; and satisfies checks a value against a type without losing its exact shape.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 5 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Write a generic Table<T> with props rows: T[], columns: { header: string; cell: (row: T) => ReactNode }[] and getKey, and render it for a list of products.
Write a Notice component whose props are either { kind: "dismissible"; onDismiss: () => void; text: string } or { kind: "static"; text: string }, and render one of each.
Explain it without notes
How does a generic List<T> component work, and what does it give callers compared with any[]?
How is a polymorphic as prop typed, and what does TypeScript check?
When would you model a component's props as a discriminated union?
What is the difference between annotating a constant and using satisfies?
Preview
Console
Nothing logged yet.Expected console output
plan: all -> Asha, Ravi
plan: free -> Ravi