option-t
Version:
A toolkit of Nullable/Option/Result type implementation in ECMAScript. Their APIs are inspired by Rust's `Option<T>` and `Result<T, E>`.
128 lines (127 loc) • 5.64 kB
TypeScript
/**
* Consider to use `Nullable<T>`, `Undefinable<T>`, or `Maybe<T>` to express an absence of a value.
* In JavaScript, they satisfy almost use cases. Probably, you might not have to use this type.
*
* --------
* This is [_option type_](https://en.wikipedia.org/wiki/Option_type).
*
* ## CAUTION:
*
* ### Be careful to use `===` or `Object.is()` to compare the equality of this type
*
* You should use `equal` operator to check the equality for two objects of this type
* instead of `===` or `Object.is()`.
* Operators for this type sometimes return the inputted object directly
* to avoid an unnecessary objecti allocation.
*
* We use this design by the assumption that we would not compare `a` and `b` usually in the following case.
* It usually suggest some design problems if you would like to compare these `a` and `b`.
*
* ```typescript
* const a = createSome(val);
* const b = andThen(a, someOperation);
* ```
*
* ## Remarks
* In almost of cases of JavaScript, it's more ergonomic to use `Nullable<T>`, `Undefinable<T>`, or `Maybe<T>`
* to represent that either there is some value or not.
* We also recommend to use them instead of this type generally.
*
* However, this type is usefil in following case:
*
* 1. Migration solution from `PlainResult<T, void>` to `Nullable<T>`, `Undefinable<T>`, or `Maybe<T>`.
* 2. You need to treat `null` or `undefined` as some value rather than absence of value.
*
* Then this tagged type helps you powerfully.
*
* @deprecated 37.1.0
*/
export type Option<T> = Some<T> | None;
/**
* This type contain some value of _T_.
*
* You can create this type value and get an inner value in this type by hand.
* But we recommend to use factory and utility functions for forward compatibility.
* And we don't recommend to implement this type for your type too.
*
* - {@link createSome()} to create a value of `Some(T)`.
* - {@link isSome()} to check whether the value is `Some(T)`.
* - {@link unwrapSome()} to get an inner value in `Some(T)`.
* - `unwrapOr()` to get either an inner value in `Some(T)` or a fallback default value.
* - ...and more.
*/
export interface Some<out T> {
/**
* Don't touch this property directly from an user project
* except 3rd party project that does not install this package but uses a value returned from an other project.
* Instead, use {@link isSome()} or {@link isNone()} operator to get an inner value.
*
* Historically, this type was created to target a JSVM that supports ES5.
* Then there was no well optimized `Symbol` to achieve a private property.
* We don't have a plan to change this into private property keep the backward compatibility.
*/
readonly ok: true;
/**
* Don't touch this property directly from an user project
* except 3rd party project that does not install this package but uses a value returned from an other project.
* Instead, use {@link unwrapSome()} operator to get an inner value.
*
* Historically, this type was created to target a JSVM that supports ES5.
* Then there was no well optimized `Symbol` to achieve a private property.
* We don't have a plan to change this into private property keep the backward compatibility.
*/
readonly val: T;
}
export declare function isSome<T>(input: Option<T>): input is Some<T>;
export declare function createSome<T>(val: T): Some<T>;
/**
* This type represents no value.
* This is a pair of `Some(T)`.
*
* You can create this type value and get an inner value in this type by hand.
* But we recommend to use factory and utility functions for forward compatibility.
* And we don't recommend to implement this type for your type too.
*
* - {@link createNone()} to create a value of `None`.
* - {@link isNone()} to check whether the value is `None`.
* - ...and more.
*/
export interface None {
/**
* Don't touch this property directly from an user project
* except 3rd party project that does not install this package but uses a value returned from an other project.
* Instead, use {@link isSome()} or {@link isNone()} operator to get an inner value.
*
* Historically, this type was created to target a JSVM that supports ES5.
* Then there was no well optimized `Symbol` to achieve a private property.
* We don't have a plan to change this into private property keep the backward compatibility.
*/
readonly ok: false;
/**
* Don't touch this property directly from an user project
* except 3rd party project that does not install this package but uses a value returned from an other project.
* Instead, use {@link unwrapSome()} operator to get an inner value.
*
* Historically, this type was created to target a JSVM that supports ES5.
* Then there was no well optimized `Symbol` to achieve a private property.
* We don't have a plan to change this into private property keep the backward compatibility.
*/
readonly val: null;
}
export declare function isNone<T>(input: Option<T>): input is None;
export declare function createNone(): None;
/**
* Return the inner `T` of a `Some(T)`.
*
* @throws {TypeError}
* Throws if the self is a `None`.
*/
export declare function unwrapSome<T>(input: Option<T>): T;
/**
* Return _input_ as `T` if the passed _input_ is `Some(T)`.
* Otherwise, throw `TypeError` with the passed `msg`.
*
* @throws {TypeError}
* Throws if the self is a `None`.
*/
export declare function expectSome<T>(input: Option<T>, msg: string): T;