Product engineering with TypeScriptModule 03 · Design patterns in TSLesson 03.5
Discriminated unions in practice
18:24 · with Carolina Rabech
type Result<T, E = HttpError> =
| { kind: 'ok'; value: T }
| { kind: 'err'; error: E }
| { kind: 'pending' };
function render(r: Result<User>) {
switch (r.kind) {
case 'pending': return <Skeleton />;
case 'err': return <Banner error={r.error} />;
case 'ok': return <Profile user={r.value} />;
}
}Lesson 03.5
07:42 / 18:24
1.0×
Carolina Rabech
Senior engineer · ex-Stone and Loft
★ 4.92·8.412 students
About this lesson
Discriminated unions are the cheapest way to get rid of nested `if-else` and let the compiler carry the context for you. In this lesson we refactor an HTTP client that mixes success, error and an in-between state into a single response — and watch the linter turn into a PR reviewer.
result.ts · refactor
type Result<T, E = HttpError> =
| { kind: 'ok'; value: T }
| { kind: 'err'; error: E }
| { kind: 'pending' };
function render(r: Result<User>) {
switch (r.kind) {
case 'pending': return <Skeleton />;
case 'err': return <Banner error={r.error} />;
case 'ok': return <Profile user={r.value} />;
}
}What this lesson covers
- How the
kinddiscriminator cuts nestedifout of every consumer. - Why
neverin the switch default is your best friend during a refactor. - Real costs: when this pattern starts to hurt, and how to work around it.
- A side-by-side comparison with try/catch and exception-based code.