Generic Result Type Implementation

mediumTypeScript

Lesson

Result Types for Explicit Error Handling

Result types are a functional programming pattern that makes error handling explicit and type-safe. Instead of throwing exceptions or returning null/undefined, functions return a Result type that can represent either success (with a value) or failure (with an error).

The key insight is that errors become part of your type system. When a function returns Result<User, DatabaseError>, you immediately know it might fail with a database error, and the compiler forces you to handle both cases.

This approach has several advantages over traditional exception handling:

Explicit Error Handling: You can't accidentally ignore errors because the type system requires you to handle both success and failure cases.

Composability: Result types work beautifully with functional programming patterns. You can chain operations that might fail without nested try-catch blocks.

Type Safety: Both your success values and error types are fully typed, giving you better autocomplete and compile-time guarantees.

Result types typically provide methods for checking the state (isOk(), isErr()), extracting values (unwrap()), and transforming success values while preserving errors (map(), flatMap()).

The pattern originated in functional languages like Haskell (Either type) and was popularized by Rust's Result enum. It's now being adopted in many languages as developers recognize the benefits of explicit error handling.

Example
1// Traditional approach with exceptions 2function divideUnsafe(a: number, b: number): number { 3 if (b === 0) { 4 throw new Error('Division by zero'); 5 } 6 return a / b; 7} 8 9// Result-based approach 10function divideSafe(a: number, b: number): Result<number, string> { 11 if (b === 0) { 12 return Result.err('Division by zero'); 13 } 14 return Result.ok(a / b); 15} 16 17// Usage - errors must be handled explicitly 18const result = divideSafe(10, 2); 19if (result.isOk()) { 20 console.log('Result:', result.unwrap()); 21} else { 22 console.log('Error:', result.unwrap()); // This would throw! 23}
L8Returns a Result type instead of throwing - errors are now explicit
L15The type system forces you to check if the operation succeeded
L18Calling unwrap() on an error would throw - you must check first

Key Takeaways

  • •Result types make error handling explicit in your type system, preventing forgotten error cases
  • •They enable functional composition of operations that might fail without exception handling complexity
  • •The pattern forces you to consciously decide how to handle each possible failure mode
Loading...