no-null
TypeScript icon, indicating that this package has built-in type declarations

2.4.0 • Public • Published

no-null

Rust-like Result and Option types for safer null-value and error handling.

Examples

Result

The Result-type represents an operation that could fail.

import { Result } from 'no-null';

// Defining a custom result type so we only have to declare the 
// expected ok-result type in our function 
type MyResult<T> = Result<T, Error> // |
                                    // V    
function failWithError(): MyResult<string> {
    try {
        throw new Error("uh-oh");
        // Result.ok() represents a successful operation
        return Result.ok("Success")
    } catch (ex) {
        // Result.err() is a failed operation
        return Result.err(ex as Error)
    }
}

const result = failWithError();

// Matching on Result.ok() and Result.err()
const innerOrDefault = result.match({
    onOk: (someString) => {
        // We can return the inner value or ...
        return someString;
    },
    onErr: (err) => {
        // ... we can return a default value in case
        // result was an err-result
        return "default value";
    }
});

console.log(innerOrDefault);

// Matching only against Result.ok()
// This can not return a value, because it 
// could also be an error
result.ifOk((someString) => {
    // ...
});

// Matching only against Result.err()
result.ifErr((err) => {
    // ...
});

if (result.isOk) {
    // ...
}
if (result.isErr) {
    // ...
}

We could also use error messages instead of an actual error

// Custom result type with error messages
type MsgResult<T> = Result<T, string>;

// This is useful if we want to display an message to an user
function fetchPrice(): MyResult<number> {
    try {
        // Fetching price could fail
        const price: number = api.fetchPrice();
        return Result.ok(price)
    } catch (ex) {
        return Result.err("No connection to server.")
    }
}

fetchPrice().match({
    onOk: (price) => {
        // Update price in UI if successful
        showPriceToUser(price);
    },
    onErr: (errMsg) => {
        // Tell user what went wrong if failed
        showErrorMsgToUser(errMsg);
    }
})

We could even go a step further and return a key to a translation file.

function fetchPrice(): MyResult<number> {
    try {
        // ...
    } catch (ex) {
        return Result.err("network.noConnectionError")
    }
}

fetchPrice().match({
    onOk: (price) => {
        showPriceToUser(price);
    },
    onErr: (errMsgKey) => {
        // Show translated error message to user
        showErrorMsgToUser(
            getTranslation(errMsgKey)
        );
    }
})

Option

The Option-type represents a value that could be null or undefined.

import { Option } from 'no-null';

function couldGetString(): Option<string> {
    const someCondition = // true/false
    return someCondition ? Option.some("Some string") : Option.none();
}

const maybeString = couldGetString();

// Matching on Option.some() and Option.none()
const innerOrDefault = maybeString.match({
    onSome: (someString) => {
        // We can return the inner value or ...
        return someString;
    },
    onNone: () => {
        // ... we can return a default value in case the 
        // option was none
        return "default value";
    }
});

console.log(innerOrDefault);

// Matching only against Option.some()
// This can not return a value, because it 
// could also be a none-option
maybeString.ifSome((someString) => {
    // ...
});

// Matching only against Option.none()
maybeString.ifNone(() => {
    // ...
});

if (maybeString.isSome) {
    // ...
}
if (maybeString.isNone) {
    // ...
}

Package Sidebar

Install

npm i no-null

Weekly Downloads

2

Version

2.4.0

License

Apache License 2.0

Unpacked Size

27.9 kB

Total Files

9

Last publish

Collaborators

  • pointless_box