Command Palette

Search for a command to run...

Hectal
Back to the lesson: Topic 12.6 — Generic and Polymorphic Components
React · Example 2 of 3

A polymorphic Text and discriminated union props

One Text component rendered six different ways, and each use was checked against its own element: htmlFor on a label, href on an a. The span with href is a type error (types are stripped here, so it still renders the attribute). Action can't be given both href and onClick, or neither.

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.

01

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.

02

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

01

How does a generic List<T> component work, and what does it give callers compared with any[]?

02

How is a polymorphic as prop typed, and what does TypeScript check?

03

When would you model a component's props as a discriminated union?

04

What is the difference between annotating a constant and using satisfies?

A polymorphic Text and discriminated union props

Preview

Press Run to see the page.

Console

Nothing logged yet.

Expected console output

<p>
<h2> id=title
<a> href=#docs
<label> for=email
<span> href=#nope
<a> href=#help
<button>
saved