npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

result-library

v1.1.4

Published

A TypeScript utility for handling success (Ok) and failure (Err) cases in a structured and type-safe manner.

Readme

Result Library

The Result library is a TypeScript utility that provides a structured way to handle success (Ok) and failure (Err) cases in your application. It is inspired by functional programming patterns and languages like Rust, enabling robust error handling without relying on exceptions.

Features

  • Type Safety: Explicitly handle Ok and Err cases with strong TypeScript typings.
  • Convenient API: Simplifies handling success and error scenarios with intuitive methods.
  • Improved Error Handling: Avoid unexpected runtime errors with structured control flows.
  • Reusable Components: Easily integrate into any TypeScript project.

Installation

npm install result-library

Usage

Simpler Version

import { Err, Ok, type Result } from 'result-library'

function maybeNumber(success: boolean): Result<number, string> {
    if(success) return new Ok(1)
    return new Err("it failed")
}

maybeNumber(true).unwrap() // 1
maybeNumber(false).unwrap_err() // "it failed"

Creating Results

To create Ok and Err results, use the ResultBuilder interface.

import { ResultBuilder } from 'result-library';

const { Ok, Err } = ResultBuilder<string, string>();

const success = Ok("Operation was successful");
const failure = Err("An error occurred");

Checking Results

if (success.is_ok()) {
  console.log("Success:", success.unwrap());
} else {
  console.error("Error:", success.err());
}

if (failure.is_err()) {
  console.error("Failure:", failure.unwrap_err());
}

Example Use Case

function divide(a: number, b: number) {
  const { Ok, Err } = ResultBuilder<number, string>();
  if (b === 0) {
    return Err("Division by zero is not allowed");
  }
  return Ok(a / b);
}

const result = divide(10, 2);
if (result.is_ok()) {
  console.log("Result:", result.unwrap());
} else {
  console.error("Error:", result.unwrap_err());
}

Advanced Usage with Types

You can define explicit types for better type safety.

const { Ok, Err } = ResultBuilder<number, string>();
const result = Ok(42);
const error = Err("Something went wrong");

if (result.is_ok()) {
  console.log(result.unwrap());
} else {
  console.error(result.unwrap_err());
}

Additional Example: Handling Multiple Cases

function fetchUserData(userId: string) {
  const { Ok, Err } = ResultBuilder<{ name: string; age: number }, string>();
  if (userId === "123") {
    return Ok({ name: "John Doe", age: 30 });
  } else {
    return Err("User not found");
  }
}

const userResult = fetchUserData("123");
if (userResult.is_ok()) {
  console.log("User Data:", userResult.unwrap());
} else {
  console.error("Error:", userResult.unwrap_err());
}

Use Case: File Processing

function processFile(filePath: string) {
  const { Ok, Err } = ResultBuilder<string, string>();

  if (!filePath.endsWith(".txt")) {
    return Err("Only .txt files are supported");
  }

  try {
    const fileContent = "File content"; // Simulate reading a file
    return Ok(fileContent);
  } catch (error) {
    return Err("Failed to process the file");
  }
}

const fileResult = processFile("example.txt");
if (fileResult.is_ok()) {
  console.log("File Content:", fileResult.unwrap());
} else {
  console.error("Error:", fileResult.unwrap_err());
}

Use Case: API Response Handling

async function fetchData(apiUrl: string) {
  const { Ok, Err } = ResultBuilder<any, string>();

  try {
    const response = await fetch(apiUrl);
    if (!response.ok) {
      return Err(`API error: ${response.status}`);
    }
    const data = await response.json();
    return Ok(data);
  } catch (error) {
    return Err("Network error");
  }
}

(async () => {
  const apiResult = await fetchData("https://api.example.com/data");
  if (apiResult.is_ok()) {
    console.log("API Data:", apiResult.unwrap());
  } else {
    console.error("Error:", apiResult.unwrap_err());
  }
})();

The Result class provides a way to handle success and error outcomes in a structured way. Below is an example demonstrating how to use Ok, Err, and the ResultBuilder to handle different results.

Code Example:

import { ResultBuilder } from 'result-library';

// deconstruct ResultBuilder and create Ok, Err builder instance
const { Ok, Err } = ResultBuilder<string, string>();

// Simulate a function that can either succeed or fail
function fetchData(success: boolean) {
  if (success) {
    return Ok('Data retrieved successfully');
  } else {
    return Err('Failed to retrieve data');
  }
}

// Simulate a success scenario
const successResult = fetchData(true);
if (successResult.is_ok()) {
  console.log(successResult.ok()); // Output: 'Data retrieved successfully'
} else {
  console.log(successResult.err());
}

// Simulate an error scenario
const errorResult = fetchData(false);
if (errorResult.is_err()) {
  console.log(errorResult.err()); // Output: 'Failed to retrieve data'
} else {
  console.log(errorResult.ok());
}

try {
  console.log(successResult.unwrap()); // Output: 'Data retrieved successfully'
  console.log(errorResult.unwrap()); // Throws error: "Called unwrap() on an Ok value"
} catch (e) {
  console.error(e.message);
}

try {
  console.log(successResult.unwrap_err()); // Throws error: "Called unwrap_err() on an Ok value"
} catch (e) {
  console.error(e.message);
}

Helper Methods Examples

These helpers make control flow expressive while remaining type-safe.

import { Ok, Err, type Result } from 'result-library';

// andThen: chain computations if Ok, otherwise propagate Err
const doubleIfOk: Result<number, string> = new Ok<number, string>(2)
  .andThen((n) => new Ok<number, string>(n * 2)); // Ok(4)

// orElse: recover from Err, pass through Ok unchanged
const recoverFromErr: Result<number, number> = new Err<string, number>('nope')
  .orElse((e) => new Err<number, number>(e.length)); // Err(4)

// expect / expectErr: unwrap with custom error messages
new Ok<number, string>(7).expect('should be ok'); // 7
// throws: Error('must be an error')
new Ok<number, string>(7).expectErr('must be an error');

// tap / tapErr: side-effects without changing the Result
let seenOk: number | undefined;
let seenErr: string | undefined;
new Ok<number, string>(3).tap((n) => { seenOk = n; }); // seenOk = 3
new Err<string, number>('bad').tapErr((e) => { seenErr = e; }); // seenErr = 'bad'

Advantages

  1. Eliminates Ambiguity: Clear distinction between success and error states.
  2. Improves Readability: Code is more declarative and self-documenting.
  3. Avoids Exceptions: Encourages error handling through return types instead of exceptions.
  4. Enhances Debugging: Easily identify and manage error cases.

API Reference

Result<A, E>

A generic class representing either a success (Ok) or failure (Err) value.

Methods:

  • is_ok(): boolean: Returns true if the result is Ok.
  • is_err(): boolean: Returns true if the result is Err.
  • ok(): A: Retrieves the success value.
  • err(): E: Retrieves the error value.
  • unwrap(): A: Returns the success value or throws an error if the result is Err.
  • unwrap_err(): E: Returns the error value or throws an error if the result is Ok.
  • unwrapErr(): E: CamelCase alias for unwrap_err().
  • when<R>({ ok, err }): R: Branch on Ok/Err and return R.
  • fold<R>({ ok, err }): Promise<R>: Async-friendly branching; handlers may return R or Promise<R>.
  • map<RT>(mapper): Result<RT, E>: Map the Ok artifact.
  • mapErr<RE>(mapper): Result<A, RE>: Map the Err error.
  • mapOr<RT>(mapper, defaultValue): RT: Map the Ok artifact, otherwise return defaultValue.
  • mapOrElse<RT>(mapper, errMapper): RT: Map the Ok artifact, otherwise compute from error.
  • mapOrErr<RE>(mapper, defaultValue): RE: On Ok, return defaultValue; on Err, map the error.
  • mapErrOr<RT>(mapper, defaultValue): RT: On Ok, return defaultValue; on Err, map the error to RT.
  • mapErrOrElse<T>(mapper, defaultValue): T: On Ok, return defaultValue; on Err, map error to T.
  • unwrapOr(defaultValue): A: Return the artifact or defaultValue.
  • unwrapOrElse(defaultValue): A: Return the artifact or compute it from error.
  • andThen<RT>(fn): Result<RT, E>: If Ok, call fn(artifact) and return its Result; if Err, propagate.
  • orElse<RE>(fn): Result<A, RE>: If Err, call fn(error) and return its Result; if Ok, propagate.
  • expect(message): A: Unwrap Ok or throw Error(message) if Err.
  • expectErr(message): E: Unwrap Err or throw Error(message) if Ok.
  • tap(fn): Result<A, E>: Run fn(artifact) when Ok; return original Result.
  • tapErr(fn): Result<A, E>: Run fn(error) when Err; return original Result.

Ok<A, E>

A subclass of Result representing a success state.

Err<E, A>

A subclass of Result representing an error state.

ResultBuilder

An interface for creating Ok and Err instances.

  • Ok<A, E>(value: A): Ok<A, E>: Creates an Ok result with the given value.
  • Err<E, A>(error: E): Err<E, A>: Creates an Err result with the given error.

Contributing

Contributions are welcome! Please open an issue or submit a pull request for enhancements or bug fixes.

License

This library is licensed under the MIT License. See LICENSE for details.