← Back to TypeScript Course | Chapter 18: Error Handling | Lesson 5 of 5

Option Type Pattern

The Option pattern represents a value that may exist or may be absent. In TypeScript, it can be modeled as a discriminated union instead of relying on null or undefined alone.
Syntax
typescript
type Option<T> = { some: true; value: T } | { some: false };

Defining an Option Type

An Option type commonly represents two states: Some, wrapping a value that's present, and None, representing an absence — this turns "maybe there's a value" into something the type system can actually enforce checking on.

Example: Defining an Option Type

typescript
type Option<T> = { kind: "some"; value: T } | { kind: "none" };
const present: Option<number> = { kind: "some", value: 5 };
console.log(present);

Creating Some and None

Helper functions like some(value) and none() keep Option values concise to create while preserving their generic type parameter, so TypeScript still knows exactly what type of value might be inside.

Example: Creating Some and None

typescript
type Option<T> = { kind: "some"; value: T } | { kind: "none" };
function some<T>(value: T): Option<T> { return { kind: "some", value }; }
function none<T>(): Option<T> { return { kind: "none" }; }
console.log(some(5), none<number>());

Checking an Option

Check the discriminant field before accessing the value so TypeScript can safely narrow the union — reading straight into an Option without checking is exactly the mistake this pattern exists to prevent.

Example: Checking an Option

typescript
type Option<T> = { kind: "some"; value: T } | { kind: "none" };
function describe(opt: Option<number>): string {
  return opt.kind === "some" ? `Value: ${opt.value}` : "No value";
}
console.log(describe({ kind: "some", value: 5 }));

Option Helper Operations

Helper operations can extract an Option's value or fall back to a default when it's absent, replacing a scattered chain of null checks with one composable operation.

Example: Option Helper Operations

typescript
type Option<T> = { kind: "some"; value: T } | { kind: "none" };
function getOrElse<T>(opt: Option<T>, fallback: T): T {
  return opt.kind === "some" ? opt.value : fallback;
}
console.log(getOrElse<number>({ kind: "none" }, 0));

When to Use Option

Option is most useful when absence is a completely normal, expected outcome — searching for an item that might not exist, or reading a configuration value that's genuinely optional — rather than treating that absence as an exceptional error.

Example: When to Use Option

typescript
type Option<T> = { kind: "some"; value: T } | { kind: "none" };
function findConfig(key: string): Option<string> {
  return key === "theme" ? { kind: "some", value: "dark" } : { kind: "none" };
}
console.log(findConfig("theme"));
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Reading opt.value without checking kind === "some", which is a compile error.
  2. Using null in one place and Option in another, making the code inconsistent.
  3. Forgetting to give none<T>() its type argument so it becomes Option<unknown>.
Chapter Summary
  • try/catch works in TypeScript, and caught errors should be handled with their types in mind.
  • Custom error classes let you create meaningful, specific error types.
  • The Result and Option type patterns represent success, failure, and missing values explicitly in the type system.
🔒

Chapter Quiz — Complete all 5 topics to unlock

0/5 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.