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-stdlib
Option<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 aSome
from a value; note that callingSome(undefined)
orSome(null)
will returnNone
None
- reference to the singletonNone
value
Querying the inner value
Option<T>.isSome(): boolean
Returns
true
if the option isSome
,false
otherwiseOption<T>.isSomeAnd(fn: (value: T) => boolean): boolean
Returns
true
if the option isSome
and callingfn
with the inner value returnstrue
,false
otherwiseOption<T>.isNone(): boolean
Returns
true
if the option isNone
,false
otherwiseOption<T>.isNoneOr(fn: (value: T) => boolean): boolean
Returns true if the option is
None
or callingfn
with the inner value returnstrue
,false
otherwiseOption<T>.unwrap(): T
Returns the underlying value if the option is
Some
, otherwise throws an exceptionOption<T>.expect(msg: string): T
Returns the underlying value if the option is
Some
, otherwise throws an exception with a custom messageOption<T>.unwrapOr(default: T): T
Returns the underlying value if the option is
Some
, otherwise returnsdefault
Option<T>.unwrapOrElse(fn: () => T): T
Returns the underlying value if the option is
Some
, otherwise callsfn
and returns its return valueOption<T>.filter(fn: (T) => boolean): Option<T>
Returns
None
if the option isNone
, otherwise callsfn
with the inner value and returns:Some<T>
with the original wrapped value iffn
returns trueNone
iffn
returns false
Option<T>.match<U>(cases: { some: (value: T) => U; none: () => U }): U
Returns 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>): boolean
Returns true if both options are
Some
and their inner values are equal using the JavaScript==
operator, or if both options areNone
. As a special case, if both options areSome
and their inner values are alsoSome
, their inner values are compared withequals()
.Option<T>.strictEquals(other: Option<T>): boolean
Returns true if both options are
Some
and their inner values are equal using the JavaScript===
operator, or if both options areNone
. As a special case, if both options areSome
and 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 withfn
Option<T>.mapOr<U>(defaultValue: U, mapFn: (value: T) => U): Option<U>
Returns an option wrapping the provided
defaultValue
if the option isNone
, or callsmapFn
with 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
defaultFn
if the option isNone
, or callsmapFn
with the inner value and returns a new option wrapping its return valueOption<T>.and<U>(other: Option<U>): Option<U>
Returns
None
if the source option isNone
, otherwise returnsother
Option<T>.andThen<U>(fn: (value: T) => Option<U>): Option<U>
Returns
None
if the source option isNone
, otherwise callsfn
with the inner value and returns the result.Option<T>.or(other: Option<T>): Option<T>
Returns the source option if it is
Some
, otherwise returnsother
Option<T>.orElse(fn: () => Option<T>): Option<T>
Returns the source option if it is
Some
, otherwise callsfn
and returns the resultOption<T>.xor(other: Option<T>) => Option<T>
Returns the source option or
other
if exactly one of them isSome
, otherwise returnsNone
Option<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 typeT
Err<E>
, representing an error containing a value of typeE
Creating a result
Ok<T, E = never>(value: T): Result<T, E>
- create anOk
result containing a success valueErr<E, T = never>(error: E): Result<T, E>
- create anErr
result 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(): boolean
Returns
true
if the result isOk
,false
otherwiseResult<T, E>.isOkAnd(fn: (value: T) => boolean): boolean
Returns
true
if the result isOk
and callingfn
with the inner value returnstrue
,false
otherwiseResult<T, E>.isErr(): boolean
Returns
true
if the result isErr
,false
otherwiseResult<T, E>.isErrAnd(fn: (error: E) => boolean): boolean
Returns
true
if the result isErr
and callingfn
with the error value returnstrue
,false
otherwiseResult<T, E>.unwrap(): T
Returns the underlying value if the result is
Ok
, otherwise throws an exceptionResult<T, E>.unwrapOr(defaultValue: T): T
Returns the underlying value if the result is
Ok
, otherwise returnsdefaultValue
Result<T, E>.unwrapOrElse(fn: () => T): T
Returns the underlying value if the result is
Ok
, otherwise callsfn
and returns its return valueResult<T, E>.unwrapErr(): E
Returns the error value if the result is
Err
, otherwise throws an exceptionResult<T, E>.expect(msg: string): T
Returns the underlying value if the result is
Ok
, otherwise throws an exception with the provided messageResult<T, E>.expectErr(msg: string): E
Returns 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 withfn
Result<T, E>.mapOr<U>(defaultValue: U, fn: (value: T) => U): Result<U, E>
Returns a result wrapping the provided
defaultValue
if the source result isErr
, or callsfn
with 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
defaultFn
if the source result isErr
, or callsmapFn
with 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 withfn
Result<T, E>.and<U>(other: Result<U, E>): Result<U, E>
Returns
other
if 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 callsfn
with 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 returnsother
Result<T, E>.orElse<U>(fn: () => Result<U, E>): Result<U, E>
Returns the source result if it is
Ok
, otherwise callsfn
and 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
fn
with 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
fn
with 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(_)
toNone
Result<T, E>.err(): Option<E>
Converts the
Result<T, E>
into anOption<E>
, mappingOk(_)
toNone
andErr(e)
toSome(e)