@binarymuse/ts-stdlib
    Preparing search index...

    Module Result

    import { Result, Ok, Err } from "@binarymuse/ts-stdlib"
    

    (For a list of methods available on Result<T, E>, see ResultMethods)

    A Result<T, E> is a value that represents either a successful computation (Ok<T>) or an error (Err<E>). It's similar to try/catch blocks, but provides a more functional approach to handling errors and composing operations that might fail.

    To create a Result representing a successful computation of type T, use the Ok function. For example: const result = Ok(value). If you want to create a Result representing an error of type E, use Err. For example: const error = Err(new Error("Something went wrong")).

    To get the successful value, call unwrap() on the Result. If the result is Err, then unwrap() will throw the error; thus, it's important to check if a result is Ok or Err before accessing the value, or use a method that provides a default value in case of Err, like unwrapOr(defaultValue).

    Result provides several methods for transforming results and handling errors in a clean, functional way. By using these methods, we can avoid many try/catch blocks and make our error handling more explicit.

    For example, here's a typical example using traditional error handling:

    interface UserAPI {
    fetchUser(id: string): Promise<User>;
    updateProfile(user: User, data: ProfileData): Promise<User>;
    sendNotification(user: User, message: string): Promise<void>;
    }

    async function updateUserProfile(
    userId: string,
    profileData: ProfileData
    ) {
    try {
    const user = await api.fetchUser(userId);
    const updatedUser = await api.updateProfile(user, profileData);
    await api.sendNotification(updatedUser, "Profile updated!");
    return updatedUser;
    } catch (error) {
    console.error("Failed to update profile:", error);
    throw error;
    }
    }

    Here's the same example using Result:

    interface UserAPI {
    fetchUser(id: string): Promise<Result<User, Error>>;
    updateProfile(user: User, data: ProfileData): Promise<Result<User, Error>>;
    sendNotification(user: User, message: string): Promise<Result<void, Error>>;
    }

    async function updateUserProfile(
    userId: string,
    profileData: ProfileData
    ): Promise<Result<User, Error>> {
    return (await api.fetchUser(userId))
    .andThen(user => api.updateProfile(user, profileData))
    .andThen(updatedUser =>
    api.sendNotification(updatedUser, "Profile updated!")
    .map(() => updatedUser)
    );
    }

    You can convert functions that might throw into Result-returning functions using the built-in Ok.try() method:

    function divide(a: number, b: number): number {
    if (b === 0) throw new Error("Division by zero");
    return a / b;
    }

    // Usage
    const result = Ok.try(() => divide(10, 2))
    .map(value => value * 2)
    .unwrapOr(0); // Returns 10

    const error = Ok.try(() => divide(10, 0))
    .map(value => value * 2)
    .unwrapOr(0); // Returns 0

    For async functions, you can convert Promises to Results using Ok.from():

    const result = await Ok.from(fetch("/api/data"))
    .andThen(response => Ok.from(response.json()))
    .mapErr(error => new Error(`Request failed: ${error}`));

    And convert Results back to Promises using toPromise():

    const result = Ok(42);
    const promise = result.toPromise(); // Promise<42>

    const error = Err(new Error("Something went wrong"));
    const promise2 = error.toPromise(); // Promise<never> (rejects)

    These methods make it easy to work with existing APIs that throw errors or return Promises while maintaining the benefits of the Result type.

    Result is particularly useful when you need to:

    • Chain multiple operations that might fail
    • Transform errors in a type-safe way
    • Provide better error context than exceptions
    • Make error handling explicit in your function signatures

    result

    ResultMethods
    Result
    Err
    Ok