result-te v0.1.6
ResultTE
Description
A simple implementation of the Result type in Typescript. Useful for \ operations that may fail or cause errors. Enforces checking and handling \ of these errors.
Documentation
The Result<T, E> type is a union of Ok and Err. Both hold and internal value \
and are monads, so can be mapped over using Result.map or Result.mapErr respectively. \
Use the helper functions Result.Ok(value) and Result.Err(message) to create a Result.
Example
import * as Result from "result-te"
const ok: Ok<string> = Result.Ok("ok")
const err: Err<string> = Result.Err("error")Helper functions are available to determine if a result is an Ok or an Err. As well \ as the match function to give a more fluent, composable way of switching on an Err or \ Ok.
if (Result.isOk(ok)) {
// do something
}
if (Result.isErr(err)) {
// do something
}
const output = Result.match({
Ok: (n: number) => `The number is: ${n}`,
Err: (m: string) => `An error occured with message: "${m}"`
})(result)
// Result === OK(5) -> output === "The number is 5"
// Result === Err("oh dear") -> output === "An error occured with message: "oh dear""
// Return types on both Ok and Err cases must be the same
// Declaring the type the parameters for each case is recommended to avoid odd
// Typescript errorsmap and mapErr
The isOk and isErr helper functions are useful for the use of procedural control \
flow. However, in order to compose functions more easily and seamlessly, Results can \
be mapped using the Result.map and Result.mapErr functions can be used.
Result.map takes a map function of T => U for a Result<T, E>.
Result.mapErr takes a map function of E => U for a Result<T, E>.
If Ok, Result.map will return a Result with a value of the return of the map \
function applied to the value of the passed in Result. \
If Err, Result.map will return the Err.
Conversely Result.mapErr will return a new Err<U> if the passed in result is an \
Err<T>, else if the passed in result is an Ok<T> it will return the Ok.
Example
// Result.map
const doubleResult = Result.map((n: number) => n * 2)
const result = doubleResult(Result.Ok(5))
// result == Ok(10)
// Result.mapErr
const appendError = Result.map((err: string) => `The error was: ${err}`)
const result = appendError(Result.Err("some failure"))
// result == Err("The error was: some failure")Result.map and Result.mapErr can be combined with Result.andThen to
compose functions fluently.
andThen
Result.andThen us used to chain together operations that have a possibility \
of failing. It type signature is as follows:
type andThen = (fn: (x: T) => Result<U, S>) => (r: Result<T, E>) => Result<U, S>If r is Err it will return an Err<E> else it will pass the value inside \
r to the function fn and return a Result<U,S> (either Ok<U> or Err<S>)
Example
import { andThen } from Result
const parseNumber = (str: string) => {
const n = parseInt(str, 10)
return !isNaN(n)
? Ok(n)
: Err("String to number parse error")
}
const validateMonthNum = (n: number) => {
return n <= 12 && n >= 1
? Ok(n)
: Err("Number must be between 1 and 12")
}
const month = andThen(validateMonth)(parseNumber(5)) // Ok(5)
const parseError = andThen(validateMonth)(parseNumber("error")) // Err("String to number parse error")
const validationError = andThen(validateMonth)(parseNumber(20)) // Err("Number must be between 1 and 12")value and message
As Typescript/ECMAScript does not have pattern matching two helper functions are \
available. One to extract the value from an Ok and one to extract the message from \
an Err.
const value = Result.value(Result.Ok("value")) // "value"
const message = Result.value(Result.Err("message")) // "message"Please note that if not using Typescript and therefore able to pass an Ok to \
Result.message or an Err to Result.value there is possibility for weirdness. \
As such in this case only use these helper functions after checking isOk or isErr