no-null
v2.4.0
Published
Rustlike option- and result-types for better null- and error-handling.
Downloads
33
Maintainers
Readme
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) {
// ...
}