Union Types — One of Many
A union type says a value can be one of several types. Written with the pipe `|`, unions are one of TypeScript's most-used features. They precisely model real-world data: an API response is either success or failure, a form field is either filled or empty, an ID is either a number or a UUID string.
Union Types — Patterns & Narrowing
// ── Basic union ────────────────────────────────────────────────
type StringOrNumber = string | number;
let id: StringOrNumber = 42;
id = "user-abc-xyz"; // ✅ also valid
// ── Union in function parameters ───────────────────────────────
function formatId(id: string | number): string {
// TypeScript only allows operations valid on BOTH types
// without narrowing — you can't call .toUpperCase() directly.
if (typeof id === "string") {
return id.toUpperCase(); // narrowed to string
}
return id.toFixed(0); // narrowed to number
}
// ── Union with null / undefined ───────────────────────────────
// With strict: true, TypeScript treats null/undefined separately.
// You must explicitly include them in unions.
function getDisplayName(name: string | null | undefined): string {
return name ?? "Anonymous"; // null-coalescing handles both
}
// ── Practical union — API response modeling ───────────────────
type ApiResponse<T> =
| { status: "success"; data: T }
| { status: "error"; error: string; code: number };
function handleResponse(res: ApiResponse<User>): void {
if (res.status === "success") {
console.log(res.data.name); // ✅ data available
} else {
console.error(res.error, res.code);
}
}
// ── Union reduction — TypeScript collapses redundant unions ───
type A = string | string; // → string
type B = string | never; // → string (never adds nothing)
type C = string | unknown; // → unknown (unknown absorbs all)
// ── Array of unions ────────────────────────────────────────────
const inputs: (string | number)[] = ["Alice", 1, "Bob", 2];Common Mistakes
- Accessing properties without narrowing — if `x: string | number`, calling `x.length` fails because `number` has no `length`. Always narrow first.
- Using `any` instead of a union — if a field can be string or number, type it `string | number`, not `any`. The union retains type safety; any throws it away.
- Forgetting `null` and `undefined` — with `strict: true`, `string` does NOT include null. Model nullable data as `string | null` explicitly.
Tip
Tip
Practice Union Types One of Many in small, isolated examples before integrating into larger projects. Breaking concepts into small experiments builds genuine understanding faster than reading alone.
interface for objects. type for unions and computed.
Practice Task
Note
Practice Task — (1) Write a working example of Union Types One of Many from scratch without looking at notes. (2) Modify it to handle an edge case (empty input, null value, or error state). (3) Share your solution in the Priygop community for feedback.
Quick Quiz
Common Mistake
Warning
A common mistake with Union Types One of Many is skipping edge case testing — empty inputs, null values, and unexpected data types. Always validate boundary conditions to write robust, production-ready typescript code.
Key Takeaways
- A union type says a value can be one of several types.
- Accessing properties without narrowing — if `x: string | number`, calling `x.length` fails because `number` has no `length`. Always narrow first.
- Using `any` instead of a union — if a field can be string or number, type it `string | number`, not `any`. The union retains type safety; any throws it away.
- Forgetting `null` and `undefined` — with `strict: true`, `string` does NOT include null. Model nullable data as `string | null` explicitly.