Union Types
Intro to Union Types
Union types allow a value to be one of several types. They're TypeScript's way
of modeling "either/or" scenariosβand a core concept in functional programming.
type StringOrNumber = string | number
let value: StringOrNumber
value = 'hello' // β
value = 42 // β
value = true // β Error
Narrowing
When you have a union type, TypeScript needs to know which specific type you're
working with before you can use type-specific methods:
function process(value: string | number) {
// Can't call .toUpperCase() yet - might be number!
if (typeof value === 'string') {
console.log(value.toUpperCase()) // β
Now TypeScript knows it's string
} else {
console.log(value.toFixed(2)) // β
Must be number
}
}
Type Guards
Sometimes
typeof checks aren't enough, especially when you need to distinguish
between object shapes. Type guards are functions that tell TypeScript which type
you have at runtime:type Cat = { meow(): void }
type Dog = { bark(): void }
type Pet = Cat | Dog
function isCat(pet: Pet): pet is Cat {
return 'meow' in pet
}
function speak(pet: Pet) {
if (isCat(pet)) {
pet.meow() // β
TypeScript knows it's Cat
} else {
pet.bark() // β
TypeScript knows it's Dog
}
}
Discriminated Unions (Algebraic Data Types)
The most powerful pattern: objects with a common "tag" property. In functional
programming, these are called algebraic data types (ADTs) or tagged
unions:
type Success = { status: 'success'; data: string }
type Error = { status: 'error'; message: string }
type Result = Success | Error
function handle(result: Result) {
if (result.status === 'success') {
console.log(result.data) // β
TypeScript knows it's Success
} else {
console.log(result.message) // β
TypeScript knows it's Error
}
}
Discriminated unions are one of TypeScript's most powerful features for
making invalid states unrepresentable. By defining exactly which states
are possible, you eliminate entire categories of bugs at compile time. This
pattern is foundational in React, Redux, and modern functional codebases.
In this exercise, you'll master union types, narrowing, and type guards.