Package Exports
- @binarymuse/ts-stdlib
- @binarymuse/ts-stdlib/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@binarymuse/ts-stdlib) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
ts-stdlib
@binarymuse/ts-stdlib is a set of classes, utilities, and types to make working with TypeScript a little bit nicer. These concepts can be found in many different languages, although many of the implementations here are inspired by Rust.
The library includes:
Option<T>- a type that represents a value (Some<T>) or the absence of one (None)Result<T, E>- a type that represents a successful result (Ok<T>) or an err (Err<E>)Rc<T>- a reference counted resource
Installation
npm install @binarymuse/ts-stdlib
# or
pnpm add @binarymuse/ts-stdlib
# or
yarn add @binarymuse/ts-stdlibOption<T>
import { Option, Some, None } from "@binarymuse/ts-stdlib"For a longer guide on using Option<T>, see docs/option.md.
An Option<T> has two variants:
Some<T>, representing the existance of the inner valueNone, representing the absence of an inner value
Creating an option
Some(value: T): Option<T>- create aSomefrom a value; note that callingSome(undefined)orSome(null)will returnNoneNone- reference to the singletonNonevalue
Querying the inner value
Option<T>.isSome(): booleanReturns
trueif the option isSome,falseotherwiseOption<T>.isSomeAnd(fn: (value: T) => boolean): booleanReturns
trueif the option isSomeand callingfnwith the inner value returnstrue,falseotherwiseOption<T>.isNone(): booleanReturns
trueif the option isNone,falseotherwiseOption<T>.isNoneOr(fn: (value: T) => boolean): booleanReturns true if the option is
Noneor callingfnwith the inner value returnstrue,falseotherwiseOption<T>.unwrap(): TReturns the underlying value if the option is
Some, otherwise throws an exceptionOption<T>.expect(msg: string): TReturns the underlying value if the option is
Some, otherwise throws an exception with a custom messageOption<T>.unwrapOr(default: T): TReturns the underlying value if the option is
Some, otherwise returnsdefaultOption<T>.unwrapOrElse(fn: () => T): TReturns the underlying value if the option is
Some, otherwise callsfnand returns its return valueOption<T>.filter(fn: (T) => boolean): Option<T>Returns
Noneif the option isNone, otherwise callsfnwith the inner value and returns:Some<T>with the original wrapped value iffnreturns trueNoneiffnreturns false
Option<T>.match<U>(cases: { some: (value: T) => U; none: () => U }): UReturns the result of calling
cases.some()with the inner value if the option isSome, otherwise returns the result of callingcases.none()Option<T>.equals(other: Option<T>): booleanReturns true if both options are
Someand their inner values are equal using the JavaScript==operator, or if both options areNone. As a special case, if both options areSomeand their inner values are alsoSome, their inner values are compared withequals().Option<T>.strictEquals(other: Option<T>): booleanReturns true if both options are
Someand their inner values are equal using the JavaScript===operator, or if both options areNone. As a special case, if both options areSomeand their inner values are alsoSome, their inner values are compared withstrictEquals().
Transforming options
Option<T>.map<U>(fn: (value: T) => U): Option<U>Returns an
Option<U>by mapping the inner value of the source option withfnOption<T>.mapOr<U>(defaultValue: U, mapFn: (value: T) => U): Option<U>Returns an option wrapping the provided
defaultValueif the option isNone, or callsmapFnwith the inner value and returns a new option wrapping its return valuemapOrElse: <U>(defaultFn: () => U, mapFn: (value: T) => U): Option<U>Returns an option wrapping the return value of
defaultFnif the option isNone, or callsmapFnwith the inner value and returns a new option wrapping its return valueOption<T>.and<U>(other: Option<U>): Option<U>Returns
Noneif the source option isNone, otherwise returnsotherOption<T>.andThen<U>(fn: (value: T) => Option<U>): Option<U>Returns
Noneif the source option isNone, otherwise callsfnwith the inner value and returns the result.Option<T>.or(other: Option<T>): Option<T>Returns the source option if it is
Some, otherwise returnsotherOption<T>.orElse(fn: () => Option<T>): Option<T>Returns the source option if it is
Some, otherwise callsfnand returns the resultOption<T>.xor(other: Option<T>) => Option<T>Returns the source option or
otherif exactly one of them isSome, otherwise returnsNoneOption<T>.flatten(): Option<T>Converts from
Option<Option<T>>toOption<T>. Only one level of nesting is removed.
Result<T, E>
import { Result, Ok, Err } from "@binarymuse/ts-stdlib"A Result<T, E> has two variants:
Ok<T>, representing a successful result containing a value of typeTErr<E>, representing an error containing a value of typeE
Creating a result
Ok<T, E = never>(value: T): Result<T, E>- create anOkresult containing a success valueErr<E, T = never>(error: E): Result<T, E>- create anErrresult containing an error value
Since TypeScript can't infer the type of E (in the case of Ok) or the type of T (in the case of Err), it can be useful to explicitly define these types when creating the Result:
const result1: Result<ValueType, ErrorType> = Ok(value);
const result2: Result<ValueType, ErrorType> = Err(error);Querying the result
Result<T, E>.isOk(): booleanReturns
trueif the result isOk,falseotherwiseResult<T, E>.isOkAnd(fn: (value: T) => boolean): booleanReturns
trueif the result isOkand callingfnwith the inner value returnstrue,falseotherwiseResult<T, E>.isErr(): booleanReturns
trueif the result isErr,falseotherwiseResult<T, E>.isErrAnd(fn: (error: E) => boolean): booleanReturns
trueif the result isErrand callingfnwith the error value returnstrue,falseotherwiseResult<T, E>.unwrap(): TReturns the underlying value if the result is
Ok, otherwise throws an exceptionResult<T, E>.unwrapOr(defaultValue: T): TReturns the underlying value if the result is
Ok, otherwise returnsdefaultValueResult<T, E>.unwrapOrElse(fn: () => T): TReturns the underlying value if the result is
Ok, otherwise callsfnand returns its return valueResult<T, E>.unwrapErr(): EReturns the error value if the result is
Err, otherwise throws an exceptionResult<T, E>.expect(msg: string): TReturns the underlying value if the result is
Ok, otherwise throws an exception with the provided messageResult<T, E>.expectErr(msg: string): EReturns the error value if the result is
Err, otherwise throws an exception with the provided message
Transforming results
Result<T, E>.map<U>(fn: (value: T) => U): Result<U, E>Returns a
Result<U, E>by mapping the success value of the source result withfnResult<T, E>.mapOr<U>(defaultValue: U, fn: (value: T) => U): Result<U, E>Returns a result wrapping the provided
defaultValueif the source result isErr, or callsfnwith the source result's success value and returns a new result wrapping its return valueResult<T, E>.mapOrElse<U>(defaultFn: () => U, mapFn: (value: T) => U): Result<U, E>Returns a result wrapping the return value of
defaultFnif the source result isErr, or callsmapFnwith the source result's success value and returns a new result wrapping its return valueResult<T, E>.mapErr<U>(fn: (error: E) => U): Result<T, U>Returns a
Result<T, U>by mapping the error value of the source result withfnResult<T, E>.and<U>(other: Result<U, E>): Result<U, E>Returns
otherif the source result isOk, otherwise returns the source result's errorResult<T, E>.andThen<U>(fn: (value: T) => Result<U, E>): Result<U, E>Returns the error if the source result is
Err, otherwise callsfnwith the success value and returns the resultResult<T, E>.or<U>(other: Result<U, E>): Result<U, E>Returns the source result if it is
Ok, otherwise returnsotherResult<T, E>.orElse<U>(fn: () => Result<U, E>): Result<U, E>Returns the source result if it is
Ok, otherwise callsfnand returns the resultResult<T, E>.flatten(): Result<T, E>Converts from
Result<Result<T, E>, E>toResult<T, E>. Only one level of nesting is removed.
Inspecting results
Result<T, E>.inspect(fn: (value: T) => void): Result<T, E>Calls
fnwith the success value if the result isOk, otherwise does nothing. Returns the original result.Result<T, E>.inspectErr(fn: (error: E) => void): Result<T, E>Calls
fnwith the error value if the result isErr, otherwise does nothing. Returns the original result.
Converting to options
Result<T, E>.ok(): Option<T>Converts the
Result<T, E>into anOption<T>, mappingOk(v)toSome(v)andErr(_)toNoneResult<T, E>.err(): Option<E>Converts the
Result<T, E>into anOption<E>, mappingOk(_)toNoneandErr(e)toSome(e)