Skip to main content
Home

Built and signed on GitHub Actions

Type-safe Result pattern for TypeScript, inspired by Rust

This package works with Cloudflare Workers, Node.js, Deno, Bun, Browsers
This package works with Cloudflare Workers
This package works with Node.js
This package works with Deno
This package works with Bun
This package works with Browsers
JSR Score
100%
Published
4 weeks ago (0.1.0)

@brettchalupa/result

A TypeScript library implementing the Result pattern for type-safe error handling, inspired by Rust's Result<T, E>.

Features

  • Type-safe error handling - Errors are part of the function signature
  • Method chaining - Fluent API for transforming and combining results
  • Zero dependencies - Lightweight and fast
  • Full TypeScript support - Complete type inference and safety
  • Well tested - Comprehensive test suite with 50+ tests

Installation

# Deno
deno add jsr:@brettchalupa/result

# pnpm 10.9+
pnpm add jsr:@brettchalupa/result

# yarn 4.9+
yarn add jsr:@brettchalupa/result

# npm, bun, and older versions of yarn or pnpm
npx jsr add @brettchalupa/result # replace npx with any of yarn dlx, pnpm dlx, or bunx

Or import directly in Deno without installation:

import { err, ok, Result } from "jsr:@brettchalupa/result";

const result = ok(42);

Quick Start

import { err, ok, type Result } from "@brettchalupa/result";

function divide(a: number, b: number): Result<number, string> {
  if (b === 0) {
    return err("Cannot divide by zero");
  }
  return ok(a / b);
}

const result = divide(10, 2);
if (result.isOk()) {
  console.log("Result:", result.data); // Result: 5
} else {
  console.error("Error:", result.error);
}

Usage

Basic Results

Create successful or failed results:

import { err, ok } from "@brettchalupa/result";

// Success
const success = ok(42);
console.log(success.data); // 42

// Failure
const failure = err("Something went wrong");
console.log(failure.error); // "Something went wrong"

Method Chaining

Transform results with a fluent API:

const result = ok(5)
  .map((x) => x * 2)
  .map((x) => x.toString()); // ok("10")

const error = err("not_found").mapErr((code) => ({
  code,
  message: "Resource not found",
}));

Handling Async Operations

import { Result } from "@brettchalupa/result";

// Wrap throwing code
const parsed = Result.try(() => JSON.parse(jsonString));

// Wrap async operations
const data = await Result.tryAsync(() => fetch(url).then((r) => r.json()));

Combining Results

import { err, ok, Result } from "@brettchalupa/result";

// Collect all successes or get first error
const results = [ok(1), ok(2), ok(3)];
const combined = Result.all(results); // ok([1, 2, 3])

// Partition successes and failures
const mixed = [ok(1), err("error"), ok(3)];
const [successes, failures] = Result.partition(mixed);
// successes: [1, 3]
// failures: ["error"]

Repository Pattern

import { err, ok, type Result } from "@brettchalupa/result";

type User = { id: string; name: string };

// Define your own domain-specific error types
type DbError = "NOT_FOUND" | "CONNECTION_ERROR" | "PERMISSION_DENIED";

async function findUser(id: string): Promise<Result<User, DbError>> {
  try {
    const user = await db.findOne({ id });
    if (!user) {
      return err("NOT_FOUND");
    }
    return ok(user);
  } catch (error) {
    return err("CONNECTION_ERROR");
  }
}

API Reference

Constructors

  • ok<T>(data: T): Ok<T> - Create a successful result
  • err<E>(error: E): Err<E> - Create a failed result

Instance Methods

Both Ok and Err types support:

  • .isOk() - Type guard for success
  • .isErr() - Type guard for failure
  • .map(fn) - Transform the success value
  • .mapErr(fn) - Transform the error value
  • .andThen(fn) - Chain operations that return Results
  • .unwrapOr(defaultValue) - Get value or default
  • .unwrap() - Get value or throw
  • .expect(message) - Get value or throw with message

Utility Functions

The Result namespace provides:

  • Result.try(fn) - Wrap a throwing function
  • Result.tryAsync(fn) - Wrap an async throwing function
  • Result.all(results) - Combine results
  • Result.partition(results) - Separate successes and failures
  • Result.collectErrors(results) - Get all errors
  • Result.map(result, fn) - Static map function
  • Result.mapErr(result, fn) - Static mapErr function
  • Result.andThen(result, fn) - Static andThen function
  • Result.unwrapOr(result, default) - Static unwrapOr function
  • Result.unwrap(result) - Static unwrap function
  • Result.expect(result, message) - Static expect function

Development

# Run tests
deno test

# Run all checks (format, lint, type check, test)
deno task ok

# Watch mode
deno task dev

License

This is free and unencumbered software released into the public domain. See UNLICENSE for details.

Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

Examples

Basic usage

import { ok, err, type Result } from "@scope/result";

function divide(a: number, b: number): Result<number, string> {
  if (b === 0) {
    return err("Cannot divide by zero");
  }
  return ok(a / b);
}

const result = divide(10, 2);
if (result.isOk()) {
  console.log('Result:', result.data); // Result: 5
} else {
  console.error('Error:', result.error);
}

Async operations

import { ok, err, type Result } from "@scope/result";

async function findUser(id: string): Promise<Result<User, DatabaseError>> {
  try {
    const user = await db.query('SELECT * FROM users WHERE id = ?', [id]);
    if (!user) {
      return err({ code: 'NOT_FOUND', message: 'User not found' });
    }
    return ok(user);
  } catch (error) {
    return err({ code: 'CONNECTION_ERROR', message: String(error) });
  }
}

Chaining operations

import { ok, err } from "@scope/result";

// Method chaining on Result instances
const result = ok({ name: "Alice", age: 30 })
  .map(user => user.name)
  .map(name => name.toUpperCase()); // ok("ALICE")

Using utility functions

import { Result } from "@scope/result";

// Safely parse JSON
const parsed = Result.try(() => JSON.parse('{"valid": "json"}'));

// Combine multiple results
const results = Result.all([ok(1), ok(2), ok(3)]); // ok([1, 2, 3])
Built and signed on
GitHub Actions

New Ticket: Report package

Please provide a reason for reporting this package. We will review your report and take appropriate action.

Please review the JSR usage policy before submitting a report.

Add Package

deno add jsr:@brettchalupa/result

Import symbol

import * as result from "@brettchalupa/result";
or

Import directly with a jsr specifier

import * as result from "jsr:@brettchalupa/result";

Add Package

pnpm i jsr:@brettchalupa/result
or (using pnpm 10.8 or older)
pnpm dlx jsr add @brettchalupa/result

Import symbol

import * as result from "@brettchalupa/result";

Add Package

yarn add jsr:@brettchalupa/result
or (using Yarn 4.8 or older)
yarn dlx jsr add @brettchalupa/result

Import symbol

import * as result from "@brettchalupa/result";

Add Package

vlt install jsr:@brettchalupa/result

Import symbol

import * as result from "@brettchalupa/result";

Add Package

npx jsr add @brettchalupa/result

Import symbol

import * as result from "@brettchalupa/result";

Add Package

bunx jsr add @brettchalupa/result

Import symbol

import * as result from "@brettchalupa/result";