Skip to content

This library provides a light Maybe type for handling optional values, inspired by functional programming languages. A Maybe can either be Just (containing a value) or Nothing (no value).

Installation

Install via npm:

Terminal window
npm install perhaps-ts

Usage

Creating Maybe Instances

You can create Maybe instances using the Just and Nothing static methods or helper functions.

import { Maybe, Just, Nothing } from "perhaps-ts";
// Using static methods
const maybeValue = Maybe.Just(5);
const noValue = Maybe.Nothing<number>();
// Using helper functions
const anotherMaybeValue = Just(10);
const anotherNoValue = Nothing<string>();

Checking for Values

You can check if a Maybe instance has a value (Just) or not (Nothing).

if (maybeValue.IsJust()) console.log("This is Just:", maybeValue.FromJust());
if (noValue.IsNothing()) console.log("This is Nothing");

Retrieving Values

To retrieve the value of a Just instance, use the FromJust or ToChecked methods. Be cautious as these methods will throw an error if called on a Nothing instance.

try {
const value = maybeValue.FromJust();
console.log("Value:", value);
} catch (error) {
console.error(error.message);
}
try {
const value = noValue.ToChecked();
} catch (error) {
console.error(error.message); // Maybe: Attempted to access value of Nothing
}

Default Values

You can provide a default value when dealing with Maybe instances, ensuring you always have a fallback.

const valueOrDefault = noValue.FromMaybe(42);
console.log("Value or Default:", valueOrDefault); // Outputs: 42

Conditional Value Extraction

You can conditionally extract the value into an output object if the instance is Just.

const output = {};
if (maybeValue.To(output)) {
console.log("Extracted Value:", output.value); // Extracted Value: 5
} else {
console.log("No value to extract");
}

Equality Comparisons

You can compare Maybe instances for equality.

const maybe1 = Just(5);
const maybe2 = Just(5);
const maybe3 = Nothing<number>();
console.log(maybe1.equals(maybe2)); // true
console.log(maybe1.equals(maybe3)); // false
console.log(maybe1.notEquals(maybe3)); // true

Sure! Here are some examples of how to write functions that return Maybe<T> instead of T | false, along with how to handle and check the returned Maybe<T> values.

Example Function Returning Maybe<T>

Let’s write a function that searches for an item in an array and returns a Maybe<T> instead of the item or false.

import { Maybe, Just, Nothing } from "maybe-type";
function findItem<T>(array: T[], predicate: (item: T) => boolean): Maybe<T> {
for (const item of array) {
if (predicate(item)) {
return Just(item);
}
}
return Nothing<T>();
}
// Usage example
const numbers = [1, 2, 3, 4, 5];
const result = findItem(numbers, (n) => n === 3);
if (result.IsJust()) {
console.log("Found:", result.FromJust()); // Found: 3
} else {
console.log("Item not found");
}

Handling and Checking Maybe<T> Values

Here are several ways to handle and check Maybe<T> values returned from functions.

Using IsJust and IsNothing

const maybeNumber = findItem(numbers, (n) => n === 6);
if (maybeNumber.IsJust()) {
console.log("Found:", maybeNumber.FromJust());
} else {
console.log("Item not found");
}

Using FromMaybe with a Default Value

const valueOrDefault = maybeNumber.FromMaybe(0);
console.log("Value or Default:", valueOrDefault); // Value or Default: 0

Using To for Conditional Extraction

const output = {};
if (maybeNumber.To(output)) {
console.log("Extracted Value:", output.value);
} else {
console.log("No value to extract");
}

Another Function Example

Let’s create another function that parses an integer from a string and returns Maybe<number>.

function parseIntMaybe(input: string): Maybe<number> {
const parsed = parseInt(input, 10);
if (isNaN(parsed)) {
return Nothing<number>();
}
return Just(parsed);
}
// Usage example
const maybeParsed = parseIntMaybe("123");
if (maybeParsed.IsJust()) {
console.log("Parsed integer:", maybeParsed.FromJust()); // Parsed integer: 123
} else {
console.log("Failed to parse integer");
}
const maybeFailedParsed = parseIntMaybe("abc");
console.log("Parsed or Default:", maybeFailedParsed.FromMaybe(0)); // Parsed or Default: 0

Returning Maybe<T> from Asynchronous Functions

Here’s an example of how to use Maybe<T> in an asynchronous function:

async function fetchData(url: string): Promise<Maybe<string>> {
try {
const response = await fetch(url);
if (!response.ok) {
return Nothing<string>();
}
const data = await response.text();
return Just(data);
} catch (error) {
return Nothing<string>();
}
}
// Usage example
fetchData("https://api.example.com/data").then((maybeData) => {
if (maybeData.IsJust()) {
console.log("Fetched Data:", maybeData.FromJust());
} else {
console.log("Failed to fetch data");
}
});

These examples demonstrate how to use the Maybe type to handle cases where values might be absent, making your code more expressive and robust.

API Reference

Maybe Class

Static Methods

  • Maybe.Just(value: T): Maybe<T>
    • Creates a Just instance containing the provided value.
  • Maybe.Nothing<T>(): Maybe<T>
    • Creates a Nothing instance with no value.

Instance Methods

  • IsJust(): boolean
    • Returns true if the instance is Just, otherwise false.
  • IsNothing(): boolean
    • Returns true if the instance is Nothing, otherwise false.
  • FromJust(): T
    • Returns the value if the instance is Just, otherwise throws an error.
  • ToChecked(): T
    • Alias for FromJust.
  • FromMaybe(defaultValue: T): T
    • Returns the value if the instance is Just, otherwise returns the provided default value.
  • To(out: { value?: T }): boolean
    • If the instance is Just, sets the value in the provided output object and returns true, otherwise returns false.
  • equals(other: Maybe<T>): boolean
    • Returns true if the other Maybe instance is equal, otherwise false.
  • notEquals(other: Maybe<T>): boolean
    • Returns true if the other Maybe instance is not equal, otherwise false.

License

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


This library simplifies handling optional values in TypeScript, providing a clear and expressive way to manage cases where a value may or may not be present.