Skip to main content
Deno 2 is finally here 🎉️
Learn more

Actions Status

Resulty

Provides simple, Rust-like Result and Option objects for Deno. This provides an alternate approach to handling errors and mixed return types.

Instead of throwing exceptions everywhere you can easily bubble up errors by returning a Result type which is either an instance of Ok or Err.

The Option objects allow you to return a standard type where the result of a method maybe something or nothing.

Setup

To add Resulty to your project simply import the ok(), err(), some() and none() methods along with the Result<T> and Opt<T> types from the Deno Land module.

import { ok, err, some, none, Result, Opt } from "https://deno.land/x/resulty/mod.ts"

Usage

The core of the this library are the ok(), err(), some() and none() methods. The ok() and err() methods return an instance of Result<T>, and the some() and none() methods return an instance of Opt<T>.

Both Result<T> and Opt<T> are wrappers for other types and objects. And you can access these contained types and objects via the unwrap() method.

import { Result, ok } from "https://deno.land/x/resulty/mod.ts";

const isOk: Result<string> = ok("Hello");

console.log(isOk.unwrap());
// Hello

One difference between Result<T> and Opt<T> objects is Result<T> objects have two additional methods to unwrap(), which are isOk() and isError(). These methods allow you to quickly confirm whether the object you have received represents a success or failure scenario.

Result

Result objects, AKA Result<T> objects, can be generated by either the ok() or err() methods. The former represents a successful outcome the latter a failure.

Result objects contain three methods, unwrap(), isOk() and isError().

In this example the code returns a Result<string>. As you see both the ok() and err() methods receive a string.

import { Result, ok, err } from "https://deno.land/x/resulty/mod.ts";

const isSandra = function (name: string): Result<string> {
  if (name === "Sandra") {
    return ok("Is Sandra");
  }
  return err("Is not Sandra");
};
  
const geoff = isSandra("Geoff");
console.log(geoff.unwrap());
// "Is not Sandra"

const sandra = isSandra("Sandra");

console.log(sandra.unwrap()); 
// "Is Sandra"

A more advanced use case may involve a situation where the ok() method receives a number and the err() method receives a string. In this scenario you can reference a union type in the Result<number | string> return type.

import { Result, ok, err } from "https://deno.land/x/resulty/mod.ts";

const findNumber = function (toFind: number): Result<number | string> {
  let numbers = [1, 4, 6, 7, 21, 33];
  
  if (numbers.includes(toFind)) {
    return ok(toFind);
  }
  return err(`Number: ${toFind} could not be found.`);
};

const found = findNumber(6);
console.log(found.unwrap());
// 6

const notFound = findNumber(9);
console.log(notFound.unwrap())
// Number: 9 could not be found.

Option

Option objects, AKA Opt<T> obejects, can be generated via the some() or none() methods. The Opt<T> object only include a single method unwrap().

Options are useful in scenarios where a system failure hasn’t occurred but either something or nothing can be returned. For instance when looking for a record in a data store of some kind.

import { Opt, some, none } from "https://deno.land/x/resulty/mod.ts";

let findRecord = function (id: number): Opt<string> {
  let records = [{id: 1, value: "Hello"}, {id: 13, value: "World"}];
  
  records = records.filter((item) => {
    return item.id === id;
  });

  if (records.length === 1) {
    return some(records[0].value);
  }

  return none();
};

const found = findRecord(13);
console.log(found.unwrap());
// "World"

const notFound = findRecord(2);
console.log(notFound.unwrap());
// null