1488 lines
56 KiB
TypeScript
1488 lines
56 KiB
TypeScript
|
/** [[include:doc/maybe.md]] */
|
|||
|
/** (keep typedoc from getting confused by the imports) */
|
|||
|
import * as Result from './result';
|
|||
|
declare type Result<T, E> = import('./result').Result<T, E>;
|
|||
|
/**
|
|||
|
Discriminant for the `Just` and `Nothing` variants.
|
|||
|
|
|||
|
You can use the discriminant via the `variant` property of `Maybe` instances
|
|||
|
if you need to match explicitly on it.
|
|||
|
*/
|
|||
|
export declare enum Variant {
|
|||
|
Just = "Just",
|
|||
|
Nothing = "Nothing"
|
|||
|
}
|
|||
|
interface JustJSON<T> {
|
|||
|
variant: Variant.Just;
|
|||
|
value: T;
|
|||
|
}
|
|||
|
interface NothingJSON {
|
|||
|
variant: Variant.Nothing;
|
|||
|
}
|
|||
|
declare type MaybeJSON<T> = JustJSON<T> | NothingJSON;
|
|||
|
/** Simply defines the common shape for `Just` and `Nothing`. */
|
|||
|
export interface MaybeShape<T> {
|
|||
|
/** Distinguish between the `Just` and `Nothing` [variants](../enums/_maybe_.variant). */
|
|||
|
readonly variant: Variant;
|
|||
|
/** Method variant for [`Maybe.isJust`](../modules/_maybe_.html#isjust) */
|
|||
|
isJust(this: Maybe<T>): this is Just<T>;
|
|||
|
/** Method variant for [`Maybe.isNothing`](../modules/_maybe_.html#isnothing) */
|
|||
|
isNothing(this: Maybe<T>): this is Nothing<T>;
|
|||
|
/** Method variant for [`Maybe.map`](../modules/_maybe_.html#map) */
|
|||
|
map<U>(this: Maybe<T>, mapFn: (t: T) => U): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.mapOr`](../modules/_maybe_.html#mapor) */
|
|||
|
mapOr<U>(this: Maybe<T>, orU: U, mapFn: (t: T) => U): U;
|
|||
|
/** Method variant for [`Maybe.mapOrElse`](../modules/_maybe_.html#maporelse) */
|
|||
|
mapOrElse<U>(this: Maybe<T>, orElseFn: () => U, mapFn: (t: T) => U): U;
|
|||
|
/** Method variant for [`Maybe.match`](../modules/_maybe_.html#match) */
|
|||
|
match<U>(this: Maybe<T>, matcher: Matcher<T, U>): U;
|
|||
|
/** Method variant for [`Maybe.or`](../modules/_maybe_.html#or) */
|
|||
|
or(this: Maybe<T>, mOr: Maybe<T>): Maybe<T>;
|
|||
|
/** Method variant for [`Maybe.orElse`](../modules/_maybe_.html#orelse) */
|
|||
|
orElse(this: Maybe<T>, orElseFn: () => Maybe<T>): Maybe<T>;
|
|||
|
/** Method variant for [`Maybe.and`](../modules/_maybe_.html#and) */
|
|||
|
and<U>(this: Maybe<T>, mAnd: Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.andThen`](../modules/_maybe_.html#andthen) */
|
|||
|
andThen<U>(this: Maybe<T>, andThenFn: (t: T) => Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.chain`](../modules/_maybe_.html#chain) */
|
|||
|
chain<U>(this: Maybe<T>, chainFn: (t: T) => Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.flatMap`](../modules/_maybe_.html#flatmap) */
|
|||
|
flatMap<U>(this: Maybe<T>, flatMapFn: (t: T) => Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.unwrap`](../modules/_maybe_.html#unwrap) */
|
|||
|
unsafelyUnwrap(): T | never;
|
|||
|
/** Method variant for [`Maybe.unwrapOrElse`](../modules/_maybe_.html#unwraporelse) */
|
|||
|
unwrapOrElse<U>(this: Maybe<T>, elseFn: () => U): T | U;
|
|||
|
/** Method variant for [`Maybe.toOkOrErr`](../modules/_maybe_.html#tookorerr) */
|
|||
|
toOkOrErr<E>(this: Maybe<T>, error: E): Result<T, E>;
|
|||
|
/** Method variant for [`Maybe.toOkOrElseErr`](../modules/_maybe_.html#tookorelseerr) */
|
|||
|
toOkOrElseErr<E>(this: Maybe<T>, elseFn: () => E): Result<T, E>;
|
|||
|
/** Method variant for [`Maybe.toString`](../modules/_maybe_.html#tostring) */
|
|||
|
toString(this: Maybe<T>): string;
|
|||
|
/** Method variant for [`Maybe.toJSON`](../modules/_maybe_.html#toJSON) */
|
|||
|
toJSON(this: Maybe<T>): MaybeJSON<T>;
|
|||
|
/** Method variant for [`Maybe.equals`](../modules/_maybe_.html#equals) */
|
|||
|
equals(this: Maybe<T>, comparison: Maybe<T>): boolean;
|
|||
|
/** Method variant for [`Maybe.ap`](../modules/_maybe_.html#ap) */
|
|||
|
ap<U>(this: Maybe<(val: T) => U>, val: Maybe<T>): Maybe<U>;
|
|||
|
/**
|
|||
|
Method variant for [`Maybe.get`](../modules/_maybe_.html#prop)
|
|||
|
|
|||
|
If you have a `Maybe` of an object type, you can do `thatMaybe.get('a key')`
|
|||
|
to look up the next layer down in the object.
|
|||
|
|
|||
|
```ts
|
|||
|
type DeepOptionalType = {
|
|||
|
something?: {
|
|||
|
with?: {
|
|||
|
deeperKeys?: string;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const fullySet: DeepType = {
|
|||
|
something: {
|
|||
|
with: {
|
|||
|
deeperKeys: 'like this'
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const deepJust = Maybe.of(fullySet)
|
|||
|
.get('something')
|
|||
|
.get('with')
|
|||
|
.get('deeperKeys');
|
|||
|
|
|||
|
console.log(deepJust); // Just('like this');
|
|||
|
|
|||
|
const partiallyUnset: DeepType = { something: { } };
|
|||
|
|
|||
|
const deepEmpty = Maybe.of(partiallyUnset)
|
|||
|
.get('something')
|
|||
|
.get('with')
|
|||
|
.get('deeperKeys');
|
|||
|
|
|||
|
console.log(deepEmpty); // Nothing
|
|||
|
```
|
|||
|
*/
|
|||
|
get<K extends keyof T>(this: Maybe<T>, key: K): Maybe<NonNullable<T[K]>>;
|
|||
|
}
|
|||
|
/**
|
|||
|
A `Just` instance is the *present* variant instance of the
|
|||
|
[`Maybe`](../modules/_maybe_.html#maybe) type, representing the presence of a
|
|||
|
value which may be absent. For a full discussion, see [the module
|
|||
|
docs](../modules/_maybe_.html).
|
|||
|
|
|||
|
@typeparam T The type wrapped in this `Just` variant of `Maybe`.
|
|||
|
*/
|
|||
|
export declare class Just<T> implements MaybeShape<T> {
|
|||
|
/**
|
|||
|
Unwrap the contained value. A convenience method for functional idioms.
|
|||
|
|
|||
|
A common scenario where you might want to use this is in a pipeline of
|
|||
|
functions:
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe, { Just } from 'true-myth/maybe';
|
|||
|
|
|||
|
function getLengths(maybeStrings: Array<Maybe<string>>): Array<number> {
|
|||
|
return maybeStrings
|
|||
|
.filter(Maybe.isJust)
|
|||
|
.map(Just.unwrap)
|
|||
|
.map(s => s.length);
|
|||
|
}
|
|||
|
```
|
|||
|
*/
|
|||
|
static unwrap<J>(theJust: Just<J>): J;
|
|||
|
/** `Just` is always [`Variant.Just`](../enums/_maybe_.variant#just). */
|
|||
|
readonly variant: Variant.Just;
|
|||
|
/** The wrapped value. */
|
|||
|
readonly value: T;
|
|||
|
/**
|
|||
|
Create an instance of `Maybe.Just` with `new`.
|
|||
|
|
|||
|
@note While you *may* create the `Just` type via normal JavaScript
|
|||
|
class construction, it is not recommended for the functional style for
|
|||
|
which the library is intended. Instead, use [`Maybe.of`] (for the general
|
|||
|
case) or [`Maybe.just`] for this specific case.
|
|||
|
|
|||
|
[`Maybe.of`]: ../modules/_maybe_.html#of
|
|||
|
[`Maybe.just`]: ../modules/_maybe_.html#just
|
|||
|
|
|||
|
```ts
|
|||
|
// Avoid:
|
|||
|
const aString = new Maybe.Just('characters');
|
|||
|
|
|||
|
// Prefer:
|
|||
|
const aString = Maybe.just('characters);
|
|||
|
```
|
|||
|
|
|||
|
@param value
|
|||
|
The value to wrap in a `Maybe.Just`.
|
|||
|
|
|||
|
`null` and `undefined` are allowed by the type signature so that the
|
|||
|
constructor may `throw` on those rather than constructing a type like
|
|||
|
`Maybe<undefined>`.
|
|||
|
|
|||
|
@throws If you pass `null` or `undefined`.
|
|||
|
*/
|
|||
|
constructor(value?: T | null);
|
|||
|
/** Method variant for [`Maybe.isJust`](../modules/_maybe_.html#isjust) */
|
|||
|
isJust(this: Maybe<T>): this is Just<T>;
|
|||
|
/** Method variant for [`Maybe.isNothing`](../modules/_maybe_.html#isnothing) */
|
|||
|
isNothing(this: Maybe<T>): this is Nothing<T>;
|
|||
|
/** Method variant for [`Maybe.map`](../modules/_maybe_.html#map) */
|
|||
|
map<U>(this: Maybe<T>, mapFn: (t: T) => U): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.mapOr`](../modules/_maybe_.html#mapor) */
|
|||
|
mapOr<U>(this: Maybe<T>, orU: U, mapFn: (t: T) => U): U;
|
|||
|
/** Method variant for [`Maybe.mapOrElse`](../modules/_maybe_.html#maporelse) */
|
|||
|
mapOrElse<U>(this: Maybe<T>, orElseFn: () => U, mapFn: (t: T) => U): U;
|
|||
|
/** Method variant for [`Maybe.match`](../modules/_maybe_.html#match) */
|
|||
|
match<U>(this: Maybe<T>, matcher: Matcher<T, U>): U;
|
|||
|
/** Method variant for [`Maybe.or`](../modules/_maybe_.html#or) */
|
|||
|
or(this: Maybe<T>, mOr: Maybe<T>): Maybe<T>;
|
|||
|
/** Method variant for [`Maybe.orElse`](../modules/_maybe_.html#orelse) */
|
|||
|
orElse(this: Maybe<T>, orElseFn: () => Maybe<T>): Maybe<T>;
|
|||
|
/** Method variant for [`Maybe.and`](../modules/_maybe_.html#and) */
|
|||
|
and<U>(this: Maybe<T>, mAnd: Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.andThen`](../modules/_maybe_.html#andthen) */
|
|||
|
andThen<U>(this: Maybe<T>, andThenFn: (t: T) => Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.chain`](../modules/_maybe_.html#chain) */
|
|||
|
chain<U>(this: Maybe<T>, chainFn: (t: T) => Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.flatMap`](../modules/_maybe_.html#flatmap) */
|
|||
|
flatMap<U>(this: Maybe<T>, flatMapFn: (t: T) => Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.unsafelyUnwrap`](../modules/_maybe_.html#unsafelyunwrap) */
|
|||
|
unsafelyUnwrap(): T;
|
|||
|
/** Method variant for [`Maybe.unwrapOr`](../modules/_maybe_.html#unwrapor) */
|
|||
|
unwrapOr<U>(this: Maybe<T>, defaultValue: U): T | U;
|
|||
|
/** Method variant for [`Maybe.unwrapOrElse`](../modules/_maybe_.html#unwraporelse) */
|
|||
|
unwrapOrElse<U>(this: Maybe<T>, elseFn: () => U): T | U;
|
|||
|
/** Method variant for [`Maybe.toOkOrErr`](../modules/_maybe_.html#tookorerr) */
|
|||
|
toOkOrErr<E>(this: Maybe<T>, error: E): Result<T, E>;
|
|||
|
/** Method variant for [`Maybe.toOkOrElseErr`](../modules/_maybe_.html#tookorelseerr) */
|
|||
|
toOkOrElseErr<E>(this: Maybe<T>, elseFn: () => E): Result<T, E>;
|
|||
|
/** Method variant for [`Maybe.toString`](../modules/_maybe_.html#tostring) */
|
|||
|
toString(this: Maybe<T>): string;
|
|||
|
/** Method variant for [`Maybe.toJSON`](../modules/_maybe_.html#toJSON) */
|
|||
|
toJSON(this: Maybe<T>): MaybeJSON<T>;
|
|||
|
/** Method variant for [`Maybe.equals`](../modules/_maybe_.html#equals) */
|
|||
|
equals(this: Maybe<T>, comparison: Maybe<T>): boolean;
|
|||
|
/** Method variant for [`Maybe.ap`](../modules/_maybe_.html#ap) */
|
|||
|
ap<A, B>(this: Maybe<(val: A) => B>, val: Maybe<A>): Maybe<B>;
|
|||
|
/**
|
|||
|
Method variant for [`Maybe.get`](../modules/_maybe_.html#prop)
|
|||
|
|
|||
|
If you have a `Maybe` of an object type, you can do `thatMaybe.get('a key')`
|
|||
|
to look up the next layer down in the object.
|
|||
|
|
|||
|
```ts
|
|||
|
type DeepOptionalType = {
|
|||
|
something?: {
|
|||
|
with?: {
|
|||
|
deeperKeys?: string;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const fullySet: DeepType = {
|
|||
|
something: {
|
|||
|
with: {
|
|||
|
deeperKeys: 'like this'
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const deepJust = Maybe.of(fullySet)
|
|||
|
.get('something')
|
|||
|
.get('with')
|
|||
|
.get('deeperKeys');
|
|||
|
|
|||
|
console.log(deepJust); // Just('like this');
|
|||
|
|
|||
|
const partiallyUnset: DeepType = { something: { } };
|
|||
|
|
|||
|
const deepEmpty = Maybe.of(partiallyUnset)
|
|||
|
.get('something')
|
|||
|
.get('with')
|
|||
|
.get('deeperKeys');
|
|||
|
|
|||
|
console.log(deepEmpty); // Nothing
|
|||
|
```
|
|||
|
*/
|
|||
|
get<K extends keyof T>(this: Maybe<T>, key: K): Maybe<NonNullable<T[K]>>;
|
|||
|
}
|
|||
|
/**
|
|||
|
A `Nothing` instance is the *absent* variant instance of the
|
|||
|
[`Maybe`](../modules/_maybe_.html#maybe) type, representing the presence of a
|
|||
|
value which may be absent. For a full discussion, see [the module
|
|||
|
docs](../modules/_maybe_.html).
|
|||
|
|
|||
|
@typeparam T The type which would be wrapped in a `Just` variant of `Maybe`.
|
|||
|
*/
|
|||
|
export declare class Nothing<T> implements MaybeShape<T> {
|
|||
|
/** `Nothing` is always [`Variant.Nothing`](../enums/_maybe_.variant#nothing). */
|
|||
|
readonly variant: Variant.Nothing;
|
|||
|
/**
|
|||
|
Create an instance of `Maybe.Nothing` with `new`.
|
|||
|
|
|||
|
@note While you *may* create the `Nothing` type via normal JavaScript
|
|||
|
class construction, it is not recommended for the functional style for
|
|||
|
which the library is intended. Instead, use [`Maybe.of`] (for the general
|
|||
|
case) or [`Maybe.nothing`] for this specific case.
|
|||
|
|
|||
|
[`Maybe.of`]: ../modules/_maybe_.html#of
|
|||
|
[`Maybe.nothing`]: ../modules/_maybe_.html#nothing
|
|||
|
|
|||
|
```ts
|
|||
|
// Avoid:
|
|||
|
const aNothing = new Maybe.Err();
|
|||
|
|
|||
|
// Prefer:
|
|||
|
const aNothing = Maybe.nothing();
|
|||
|
```
|
|||
|
|
|||
|
`null` and `undefined` are allowed so that you may explicitly construct the
|
|||
|
`Err` type with a known `null` or `undefined` value. (This maybe helpful
|
|||
|
primarily when transitioning a codebase to the use of `Maybe`.)
|
|||
|
|
|||
|
@throws If you pass `null` or `undefined`.
|
|||
|
*/
|
|||
|
constructor(_?: null);
|
|||
|
/** Method variant for [`Maybe.isJust`](../modules/_maybe_.html#isjust) */
|
|||
|
isJust(this: Maybe<T>): this is Just<T>;
|
|||
|
/** Method variant for [`Maybe.isNothing`](../modules/_maybe_.html#isnothing) */
|
|||
|
isNothing(this: Maybe<T>): this is Nothing<T>;
|
|||
|
/** Method variant for [`Maybe.map`](../modules/_maybe_.html#map) */
|
|||
|
map<U>(this: Maybe<T>, mapFn: (t: T) => U): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.mapOr`](../modules/_maybe_.html#mapor) */
|
|||
|
mapOr<U>(this: Maybe<T>, orU: U, mapFn: (t: T) => U): U;
|
|||
|
/** Method variant for [`Maybe.mapOrElse`](../modules/_maybe_.html#maporelse) */
|
|||
|
mapOrElse<U>(this: Maybe<T>, orElseFn: () => U, mapFn: (t: T) => U): U;
|
|||
|
/** Method variant for [`Maybe.match`](../modules/_maybe_.html#match) */
|
|||
|
match<U>(this: Maybe<T>, matcher: Matcher<T, U>): U;
|
|||
|
/** Method variant for [`Maybe.or`](../modules/_maybe_.html#or) */
|
|||
|
or(this: Maybe<T>, mOr: Maybe<T>): Maybe<T>;
|
|||
|
/** Method variant for [`Maybe.orElse`](../modules/_maybe_.html#orelse) */
|
|||
|
orElse(this: Maybe<T>, orElseFn: () => Maybe<T>): Maybe<T>;
|
|||
|
/** Method variant for [`Maybe.and`](../modules/_maybe_.html#and) */
|
|||
|
and<U>(this: Maybe<T>, mAnd: Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.andThen`](../modules/_maybe_.html#andthen) */
|
|||
|
andThen<U>(this: Maybe<T>, andThenFn: (t: T) => Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.chain`](../modules/_maybe_.html#chain) */
|
|||
|
chain<U>(this: Maybe<T>, chainFn: (t: T) => Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.flatMap`](../modules/_maybe_.html#flatmap) */
|
|||
|
flatMap<U>(this: Maybe<T>, flatMapFn: (t: T) => Maybe<U>): Maybe<U>;
|
|||
|
/** Method variant for [`Maybe.unsafelyUnwrap`](../modules/_maybe_.html#unsafelyunwrap) */
|
|||
|
unsafelyUnwrap(): never;
|
|||
|
/** Method variant for [`Maybe.unwrapOr`](../modules/_maybe_.html#unwrapor) */
|
|||
|
unwrapOr<U>(this: Maybe<T>, defaultValue: U): T | U;
|
|||
|
/** Method variant for [`Maybe.unwrapOrElse`](../modules/_maybe_.html#unwraporelse) */
|
|||
|
unwrapOrElse<U>(this: Maybe<T>, elseFn: () => U): T | U;
|
|||
|
/** Method variant for [`Maybe.toOkOrErr`](../modules/_maybe_.html#tookorerr) */
|
|||
|
toOkOrErr<E>(this: Maybe<T>, error: E): Result<T, E>;
|
|||
|
/** Method variant for [`Maybe.toOkOrElseErr`](../modules/_maybe_.html#tookorelseerr) */
|
|||
|
toOkOrElseErr<E>(this: Maybe<T>, elseFn: () => E): Result<T, E>;
|
|||
|
/** Method variant for [`Maybe.toString`](../modules/_maybe_.html#tostring) */
|
|||
|
toString(this: Maybe<T>): string;
|
|||
|
/** Method variant for [`Maybe.toJSON`](../modules/_maybe_.html#toJSON) */
|
|||
|
toJSON(this: Maybe<T>): MaybeJSON<T>;
|
|||
|
/** Method variant for [`Maybe.equals`](../modules/_maybe_.html#equals) */
|
|||
|
equals(this: Maybe<T>, comparison: Maybe<T>): boolean;
|
|||
|
/** Method variant for [`Maybe.ap`](../modules/_maybe_.html#ap) */
|
|||
|
ap<A, B>(this: Maybe<(val: A) => B>, val: Maybe<A>): Maybe<B>;
|
|||
|
/**
|
|||
|
Method variant for [`Maybe.get`](../modules/_maybe_.html#prop)
|
|||
|
|
|||
|
If you have a `Maybe` of an object type, you can do `thatMaybe.get('a key')`
|
|||
|
to look up the next layer down in the object.
|
|||
|
|
|||
|
```ts
|
|||
|
type DeepOptionalType = {
|
|||
|
something?: {
|
|||
|
with?: {
|
|||
|
deeperKeys?: string;
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const fullySet: DeepType = {
|
|||
|
something: {
|
|||
|
with: {
|
|||
|
deeperKeys: 'like this'
|
|||
|
}
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const deepJust = Maybe.of(fullySet)
|
|||
|
.get('something')
|
|||
|
.get('with')
|
|||
|
.get('deeperKeys');
|
|||
|
|
|||
|
console.log(deepJust); // Just('like this');
|
|||
|
|
|||
|
const partiallyUnset: DeepType = { something: { } };
|
|||
|
|
|||
|
const deepEmpty = Maybe.of(partiallyUnset)
|
|||
|
.get('something')
|
|||
|
.get('with')
|
|||
|
.get('deeperKeys');
|
|||
|
|
|||
|
console.log(deepEmpty); // Nothing
|
|||
|
```
|
|||
|
*/
|
|||
|
get<K extends keyof T>(this: Maybe<T>, key: K): Maybe<NonNullable<T[K]>>;
|
|||
|
}
|
|||
|
/**
|
|||
|
Is this result a `Just` instance?
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@param maybe The `Maybe` instance to check.
|
|||
|
@returns `true` if `maybe` is `Just`, `false` otherwise. In TypeScript,
|
|||
|
also narrows the type from `Maybe<T>` to `Just<T>`.
|
|||
|
*/
|
|||
|
export declare function isJust<T>(maybe: Maybe<T>): maybe is Just<T>;
|
|||
|
/**
|
|||
|
Is this result a `Nothing` instance?
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@param maybe The `Maybe` instance to check.
|
|||
|
@returns `true` if `maybe` is `nothing`, `false` otherwise. In TypeScript,
|
|||
|
also narrows the type from `Maybe<T>` to `Nothing<T>`.
|
|||
|
*/
|
|||
|
export declare function isNothing<T>(maybe: Maybe<T>): maybe is Nothing<T>;
|
|||
|
/**
|
|||
|
Create an instance of `Maybe.Just`.
|
|||
|
|
|||
|
`null` and `undefined` are allowed by the type signature so that the
|
|||
|
function may `throw` on those rather than constructing a type like
|
|||
|
`Maybe<undefined>`.
|
|||
|
|
|||
|
@typeparam T The type of the item contained in the `Maybe`.
|
|||
|
@param value The value to wrap in a `Maybe.Just`.
|
|||
|
@returns An instance of `Maybe.Just<T>`.
|
|||
|
@throws If you pass `null` or `undefined`.
|
|||
|
*/
|
|||
|
export declare function just<T = unknown>(value?: T | null): Maybe<T>;
|
|||
|
/**
|
|||
|
Create an instance of `Maybe.Nothing`.
|
|||
|
|
|||
|
If you want to create an instance with a specific type, e.g. for use in a
|
|||
|
function which expects a `Maybe<T>` where the `<T>` is known but you have no
|
|||
|
value to give it, you can use a type parameter:
|
|||
|
|
|||
|
```ts
|
|||
|
const notString = Maybe.nothing<string>();
|
|||
|
```
|
|||
|
|
|||
|
@typeparam T The type of the item contained in the `Maybe`.
|
|||
|
@returns An instance of `Maybe.Nothing<T>`.
|
|||
|
*/
|
|||
|
export declare function nothing<T = unknown>(_?: null): Maybe<T>;
|
|||
|
/**
|
|||
|
Create a `Maybe` from any value.
|
|||
|
|
|||
|
To specify that the result should be interpreted as a specific type, you may
|
|||
|
invoke `Maybe.of` with an explicit type parameter:
|
|||
|
|
|||
|
```ts
|
|||
|
const foo = Maybe.of<string>(null);
|
|||
|
```
|
|||
|
|
|||
|
This is usually only important in two cases:
|
|||
|
|
|||
|
1. If you are intentionally constructing a `Nothing` from a known `null` or
|
|||
|
undefined value *which is untyped*.
|
|||
|
2. If you are specifying that the type is more general than the value passed
|
|||
|
(since TypeScript can define types as literals).
|
|||
|
|
|||
|
@typeparam T The type of the item contained in the `Maybe`.
|
|||
|
@param value The value to wrap in a `Maybe`. If it is `undefined` or `null`,
|
|||
|
the result will be `Nothing`; otherwise it will be the type of
|
|||
|
the value passed.
|
|||
|
*/
|
|||
|
export declare function of<T>(value?: T | null): Maybe<T>;
|
|||
|
/**
|
|||
|
Alias for [`of`](#of), convenient for a standalone import:
|
|||
|
|
|||
|
```ts
|
|||
|
import { maybe } from 'true-myth/maybe';
|
|||
|
|
|||
|
interface Dict<T> {
|
|||
|
[key: string]: T | null | undefined;
|
|||
|
}
|
|||
|
|
|||
|
interface StrictDict<T> {
|
|||
|
[key: string]: Maybe<T>;
|
|||
|
}
|
|||
|
|
|||
|
function wrapNullables<T>(dict: Dict<T>): StrictDict<T> {
|
|||
|
return Object.keys(dict).reduce((strictDict, key) => {
|
|||
|
strictDict[key] = maybe(dict[key]);
|
|||
|
return strictDict;
|
|||
|
}, {} as StrictDict<T>);
|
|||
|
}
|
|||
|
```
|
|||
|
*/
|
|||
|
export declare const maybe: typeof of;
|
|||
|
/** Alias for [`of`](#of), primarily for compatibility with Folktale. */
|
|||
|
export declare const fromNullable: typeof of;
|
|||
|
/**
|
|||
|
Map over a `Maybe` instance: apply the function to the wrapped value if the
|
|||
|
instance is `Just`, and return `Nothing` if the instance is `Nothing`.
|
|||
|
|
|||
|
`Maybe.map` works a lot like `Array.prototype.map`: `Maybe` and `Array` are
|
|||
|
both *containers* for other things. If you have no items in an array of
|
|||
|
numbers named `foo` and call `foo.map(x => x + 1)`, you'll still just have an
|
|||
|
array with nothing in it. But if you have any items in the array (`[2, 3]`),
|
|||
|
and you call `foo.map(x => x + 1)` on it, you'll get a new array with each of
|
|||
|
those items inside the array "container" transformed (`[3, 4]`).
|
|||
|
|
|||
|
That's exactly what's happening with `Maybe.map`. If the container is *empty*
|
|||
|
– the `Nothing` variant – you just get back an empty container. If the
|
|||
|
container has something in it – the `Just` variant – you get back a container
|
|||
|
with the item inside transformed.
|
|||
|
|
|||
|
(So... why not just use an array? The biggest reason is that an array can be
|
|||
|
any length. With a `Maybe`, we're capturing the idea of "something or
|
|||
|
nothing" rather than "0 to n" items. And this lets us implement a whole set
|
|||
|
of *other* interfaces, like those in this module.)
|
|||
|
|
|||
|
#### Examples
|
|||
|
|
|||
|
```ts
|
|||
|
const length = (s: string) => s.length;
|
|||
|
|
|||
|
const justAString = Maybe.just('string');
|
|||
|
const justTheStringLength = map(length, justAString);
|
|||
|
console.log(justTheStringLength.toString()); // Just(6)
|
|||
|
|
|||
|
const notAString = Maybe.nothing<string>();
|
|||
|
const notAStringLength = map(length, notAString);
|
|||
|
console.log(notAStringLength.toString()); // "Nothing"
|
|||
|
```
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@typeparam U The type of the wrapped value of the returned `Maybe`.
|
|||
|
@param mapFn The function to apply the value to if `Maybe` is `Just`.
|
|||
|
@param maybe The `Maybe` instance to map over.
|
|||
|
@returns A new `Maybe` with the result of applying `mapFn` to the value
|
|||
|
in a `Just`, or `Nothing` if `maybe` is `Nothing`.
|
|||
|
*/
|
|||
|
export declare function map<T, U>(mapFn: (t: T) => U): (maybe: Maybe<T>) => Maybe<U>;
|
|||
|
export declare function map<T, U>(mapFn: (t: T) => U, maybe: Maybe<T>): Maybe<U>;
|
|||
|
/**
|
|||
|
Map over a `Maybe` instance and get out the value if `maybe` is a `Just`, or
|
|||
|
return a default value if `maybe` is a `Nothing`.
|
|||
|
|
|||
|
#### Examples
|
|||
|
|
|||
|
```ts
|
|||
|
const length = (s: string) => s.length;
|
|||
|
|
|||
|
const justAString = Maybe.just('string');
|
|||
|
const theStringLength = mapOr(0, length, justAString);
|
|||
|
console.log(theStringLength); // 6
|
|||
|
|
|||
|
const notAString = Maybe.nothing<string>();
|
|||
|
const notAStringLength = mapOr(0, length, notAString)
|
|||
|
console.log(notAStringLength); // 0
|
|||
|
```
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@typeparam U The type of the wrapped value of the returned `Maybe`.
|
|||
|
@param orU The default value to use if `maybe` is `Nothing`
|
|||
|
@param mapFn The function to apply the value to if `Maybe` is `Just`
|
|||
|
@param maybe The `Maybe` instance to map over.
|
|||
|
*/
|
|||
|
export declare function mapOr<T, U>(orU: U, mapFn: (t: T) => U, maybe: Maybe<T>): U;
|
|||
|
export declare function mapOr<T, U>(orU: U, mapFn: (t: T) => U): (maybe: Maybe<T>) => U;
|
|||
|
export declare function mapOr<T, U>(orU: U): (mapFn: (t: T) => U) => (maybe: Maybe<T>) => U;
|
|||
|
/**
|
|||
|
Map over a `Maybe` instance and get out the value if `maybe` is a `Just`,
|
|||
|
or use a function to construct a default value if `maybe` is `Nothing`.
|
|||
|
|
|||
|
#### Examples
|
|||
|
|
|||
|
```ts
|
|||
|
const length = (s: string) => s.length;
|
|||
|
const getDefault = () => 0;
|
|||
|
|
|||
|
const justAString = Maybe.just('string');
|
|||
|
const theStringLength = mapOrElse(getDefault, length, justAString);
|
|||
|
console.log(theStringLength); // 6
|
|||
|
|
|||
|
const notAString = Maybe.nothing<string>();
|
|||
|
const notAStringLength = mapOrElse(getDefault, length, notAString)
|
|||
|
console.log(notAStringLength); // 0
|
|||
|
```
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@typeparam U The type of the wrapped value of the returned `Maybe`.
|
|||
|
@param orElseFn The function to apply if `maybe` is `Nothing`.
|
|||
|
@param mapFn The function to apply to the wrapped value if `maybe` is `Just`
|
|||
|
@param maybe The `Maybe` instance to map over.
|
|||
|
*/
|
|||
|
export declare function mapOrElse<T, U>(orElseFn: () => U, mapFn: (t: T) => U, maybe: Maybe<T>): U;
|
|||
|
export declare function mapOrElse<T, U>(orElseFn: () => U, mapFn: (t: T) => U): (maybe: Maybe<T>) => U;
|
|||
|
export declare function mapOrElse<T, U>(orElseFn: () => U): (mapFn: (t: T) => U) => (maybe: Maybe<T>) => U;
|
|||
|
/**
|
|||
|
You can think of this like a short-circuiting logical "and" operation on a
|
|||
|
`Maybe` type. If `maybe` is `Just`, then the result is the `andMaybe`. If
|
|||
|
`maybe` is `Nothing`, the result is `Nothing`.
|
|||
|
|
|||
|
This is useful when you have another `Maybe` value you want to provide if and
|
|||
|
*only if* you have a `Just` – that is, when you need to make sure that if you
|
|||
|
`Nothing`, whatever else you're handing a `Maybe` to *also* gets a `Nothing`.
|
|||
|
|
|||
|
Notice that, unlike in [`map`](#map) or its variants, the original `maybe` is
|
|||
|
not involved in constructing the new `Maybe`.
|
|||
|
|
|||
|
#### Examples
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
const justA = Maybe.just('A');
|
|||
|
const justB = Maybe.just('B');
|
|||
|
const nothing: Maybe<number> = nothing();
|
|||
|
|
|||
|
console.log(Maybe.and(justB, justA).toString()); // Just(B)
|
|||
|
console.log(Maybe.and(justB, nothing).toString()); // Nothing
|
|||
|
console.log(Maybe.and(nothing, justA).toString()); // Nothing
|
|||
|
console.log(Maybe.and(nothing, nothing).toString()); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
@typeparam T The type of the initial wrapped value.
|
|||
|
@typeparam U The type of the wrapped value of the returned `Maybe`.
|
|||
|
@param andMaybe The `Maybe` instance to return if `maybe` is `Just`
|
|||
|
@param maybe The `Maybe` instance to check.
|
|||
|
@return `Nothing` if the original `maybe` is `Nothing`, or `andMaybe`
|
|||
|
if the original `maybe` is `Just`.
|
|||
|
*/
|
|||
|
export declare function and<T, U>(andMaybe: Maybe<U>, maybe: Maybe<T>): Maybe<U>;
|
|||
|
export declare function and<T, U>(andMaybe: Maybe<U>): (maybe: Maybe<T>) => Maybe<U>;
|
|||
|
/**
|
|||
|
Apply a function to the wrapped value if `Just` and return a new `Just`
|
|||
|
containing the resulting value; or return `Nothing` if `Nothing`.
|
|||
|
|
|||
|
This differs from `map` in that `thenFn` returns another `Maybe`. You can use
|
|||
|
`andThen` to combine two functions which *both* create a `Maybe` from an
|
|||
|
unwrapped type.
|
|||
|
|
|||
|
You may find the `.then` method on an ES6 `Promise` helpful for b:
|
|||
|
if you have a `Promise`, you can pass its `then` method a callback which
|
|||
|
returns another `Promise`, and the result will not be a *nested* promise, but
|
|||
|
a single `Promise`. The difference is that `Promise#then` unwraps *all*
|
|||
|
layers to only ever return a single `Promise` value, whereas `Maybe.andThen`
|
|||
|
will not unwrap nested `Maybe`s.
|
|||
|
|
|||
|
This is also commonly known as (and therefore aliased as) [`flatMap`][flatMap]
|
|||
|
or [`chain`][chain]. It is sometimes also known as `bind`, but *not* aliased as such
|
|||
|
because [`bind` already means something in JavaScript][bind].
|
|||
|
|
|||
|
[flatMap]: #flatmap
|
|||
|
[chain]: #chain
|
|||
|
[bind]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind
|
|||
|
|
|||
|
#### Example
|
|||
|
|
|||
|
(This is a somewhat contrived example, but it serves to show the way the
|
|||
|
function behaves.)
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
// string -> Maybe<number>
|
|||
|
const toMaybeLength = (s: string): Maybe<number> => Maybe.of(s.length);
|
|||
|
|
|||
|
// Maybe<string>
|
|||
|
const aMaybeString = Maybe.of('Hello, there!');
|
|||
|
|
|||
|
// Maybe<number>
|
|||
|
const resultingLength = Maybe.andThen(toMaybeLength, aMaybeString);
|
|||
|
console.log(Maybe.toString(resultingLength)); // 13
|
|||
|
```
|
|||
|
|
|||
|
Note that the result is not `(Just(13))`, but `13`!
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@typeparam U The type of the wrapped value in the resulting `Maybe`.
|
|||
|
@param thenFn The function to apply to the wrapped `T` if `maybe` is `Just`.
|
|||
|
@param maybe The `Maybe` to evaluate and possibly apply a function to the
|
|||
|
contents of.
|
|||
|
@returns The result of the `thenFn` (a new `Maybe`) if `maybe` is a
|
|||
|
`Just`, otherwise `Nothing` if `maybe` is a `Nothing`.
|
|||
|
*/
|
|||
|
export declare function andThen<T, U>(thenFn: (t: T) => Maybe<U>, maybe: Maybe<T>): Maybe<U>;
|
|||
|
export declare function andThen<T, U>(thenFn: (t: T) => Maybe<U>): (maybe: Maybe<T>) => Maybe<U>;
|
|||
|
/** Alias for [`andThen`](#andthen). */
|
|||
|
export declare const chain: typeof andThen;
|
|||
|
/** Alias for [`andThen`](#andthen). */
|
|||
|
export declare const flatMap: typeof andThen;
|
|||
|
/** Alias for [`andThen`](#andthen). */
|
|||
|
export declare const bind: typeof andThen;
|
|||
|
/**
|
|||
|
Provide a fallback for a given `Maybe`. Behaves like a logical `or`: if the
|
|||
|
`maybe` value is a `Just`, returns that `maybe`; otherwise, returns the
|
|||
|
`defaultMaybe` value.
|
|||
|
|
|||
|
This is useful when you want to make sure that something which takes a
|
|||
|
`Maybe` always ends up getting a `Just` variant, by supplying a default value
|
|||
|
for the case that you currently have a nothing.
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-utils/maybe';
|
|||
|
|
|||
|
const justA = Maybe.just("a");
|
|||
|
const justB = Maybe.just("b");
|
|||
|
const aNothing: Maybe<string> = nothing();
|
|||
|
|
|||
|
console.log(Maybe.or(justB, justA).toString()); // Just(A)
|
|||
|
console.log(Maybe.or(aNothing, justA).toString()); // Just(A)
|
|||
|
console.log(Maybe.or(justB, aNothing).toString()); // Just(B)
|
|||
|
console.log(Maybe.or(aNothing, aNothing).toString()); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@param defaultMaybe The `Maybe` to use if `maybe` is a `Nothing`.
|
|||
|
@param maybe The `Maybe` instance to evaluate.
|
|||
|
@returns `maybe` if it is a `Just`, otherwise `defaultMaybe`.
|
|||
|
*/
|
|||
|
export declare function or<T>(defaultMaybe: Maybe<T>, maybe: Maybe<T>): Maybe<T>;
|
|||
|
export declare function or<T>(defaultMaybe: Maybe<T>): (maybe: Maybe<T>) => Maybe<T>;
|
|||
|
/**
|
|||
|
Like `or`, but using a function to construct the alternative `Maybe`.
|
|||
|
|
|||
|
Sometimes you need to perform an operation using other data in the
|
|||
|
environment to construct the fallback value. In these situations, you can
|
|||
|
pass a function (which may be a closure) as the `elseFn` to generate the
|
|||
|
fallback `Maybe<T>`.
|
|||
|
|
|||
|
Useful for transforming empty scenarios based on values in context.
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@param elseFn The function to apply if `maybe` is `Nothing`
|
|||
|
@param maybe The `maybe` to use if it is `Just`.
|
|||
|
@returns The `maybe` if it is `Just`, or the `Maybe` returned by
|
|||
|
`elseFn` if the `maybe` is `Nothing`.
|
|||
|
*/
|
|||
|
export declare function orElse<T>(elseFn: () => Maybe<T>, maybe: Maybe<T>): Maybe<T>;
|
|||
|
export declare function orElse<T>(elseFn: () => Maybe<T>): (maybe: Maybe<T>) => Maybe<T>;
|
|||
|
/**
|
|||
|
Get the value out of the `Maybe`.
|
|||
|
|
|||
|
Returns the content of a `Just`, but **throws if the `Maybe` is `Nothing`**.
|
|||
|
Prefer to use [`unwrapOr`](#unwrapor) or [`unwrapOrElse`](#unwraporelse).
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@param maybe The value to unwrap
|
|||
|
@returns The unwrapped value if the `Maybe` instance is `Just`.
|
|||
|
@throws If the `maybe` is `Nothing`.
|
|||
|
*/
|
|||
|
export declare function unsafelyUnwrap<T>(maybe: Maybe<T>): T;
|
|||
|
/** Alias for [`unsafelyUnwrap`](#unsafelyunwrap) */
|
|||
|
export declare const unsafelyGet: typeof unsafelyUnwrap;
|
|||
|
/** Alias for [`unsafelyUnwrap`](#unsafelyunwrap) */
|
|||
|
export declare const unsafeGet: typeof unsafelyUnwrap;
|
|||
|
/**
|
|||
|
Safely get the value out of a `Maybe`.
|
|||
|
|
|||
|
Returns the content of a `Just` or `defaultValue` if `Nothing`. This is the
|
|||
|
recommended way to get a value out of a `Maybe` most of the time.
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
const notAString = Maybe.nothing<string>();
|
|||
|
const isAString = Maybe.just('look ma! some characters!');
|
|||
|
|
|||
|
console.log(Maybe.unwrapOr('<empty>', notAString)); // "<empty>"
|
|||
|
console.log(Maybe.unwrapOr('<empty>', isAString)); // "look ma! some characters!"
|
|||
|
```
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value.
|
|||
|
@param defaultValue The value to return if `maybe` is a `Nothing`.
|
|||
|
@param maybe The `Maybe` instance to unwrap if it is a `Just`.
|
|||
|
@returns The content of `maybe` if it is a `Just`, otherwise
|
|||
|
`defaultValue`.
|
|||
|
*/
|
|||
|
export declare function unwrapOr<T, U>(defaultValue: U, maybe: Maybe<T>): T | U;
|
|||
|
export declare function unwrapOr<T, U>(defaultValue: U): (maybe: Maybe<T>) => T | U;
|
|||
|
/** Alias for [`unwrapOr`](#unwrapor) */
|
|||
|
export declare const getOr: typeof unwrapOr;
|
|||
|
/**
|
|||
|
Safely get the value out of a [`Maybe`](#maybe) by returning the wrapped
|
|||
|
value if it is `Just`, or by applying `orElseFn` if it is `Nothing`.
|
|||
|
|
|||
|
This is useful when you need to *generate* a value (e.g. by using current
|
|||
|
values in the environment – whether preloaded or by local closure) instead of
|
|||
|
having a single default value available (as in [`unwrapOr`](#unwrapor)).
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
// You can imagine that someOtherValue might be dynamic.
|
|||
|
const someOtherValue = 99;
|
|||
|
const handleNothing = () => someOtherValue;
|
|||
|
|
|||
|
const aJust = Maybe.just(42);
|
|||
|
console.log(Maybe.unwrapOrElse(handleNothing, aJust)); // 42
|
|||
|
|
|||
|
const aNothing = nothing<number>();
|
|||
|
console.log(Maybe.unwrapOrElse(handleNothing, aNothing)); // 99
|
|||
|
```
|
|||
|
|
|||
|
@typeparam T The wrapped value.
|
|||
|
@param orElseFn A function used to generate a valid value if `maybe` is a
|
|||
|
`Nothing`.
|
|||
|
@param maybe The `Maybe` instance to unwrap if it is a `Just`
|
|||
|
@returns Either the content of `maybe` or the value returned from
|
|||
|
`orElseFn`.
|
|||
|
*/
|
|||
|
export declare function unwrapOrElse<T, U>(orElseFn: () => U, maybe: Maybe<T>): T | U;
|
|||
|
export declare function unwrapOrElse<T, U>(orElseFn: () => U): (maybe: Maybe<T>) => T | U;
|
|||
|
/** Alias for [`unwrapOrElse`](#unwraporelse) */
|
|||
|
export declare const getOrElse: typeof unwrapOrElse;
|
|||
|
/**
|
|||
|
Transform the [`Maybe`](#maybe) into a
|
|||
|
[`Result`](../modules/_result_.html#result), using the wrapped value as the
|
|||
|
`Ok` value if `Just`; otherwise using the supplied `error` value for `Err`.
|
|||
|
|
|||
|
@typeparam T The wrapped value.
|
|||
|
@typeparam E The error type to in the `Result`.
|
|||
|
@param error The error value to use if the `Maybe` is `Nothing`.
|
|||
|
@param maybe The `Maybe` instance to convert.
|
|||
|
@returns A `Result` containing the value wrapped in `maybe` in an `Ok`,
|
|||
|
or `error` in an `Err`.
|
|||
|
*/
|
|||
|
export declare function toOkOrErr<T, E>(error: E, maybe: Maybe<T>): Result<T, E>;
|
|||
|
export declare function toOkOrErr<T, E>(error: E): (maybe: Maybe<T>) => Result<T, E>;
|
|||
|
/**
|
|||
|
Transform the [`Maybe`](#maybe) into a
|
|||
|
[`Result`](../modules/_result_.html#result), using the wrapped value as the
|
|||
|
`Ok` value if `Just`; otherwise using `elseFn` to generate `Err`.
|
|||
|
|
|||
|
@typeparam T The wrapped value.
|
|||
|
@typeparam E The error type to in the `Result`.
|
|||
|
@param elseFn The function which generates an error of type `E`.
|
|||
|
@param maybe The `Maybe` instance to convert.
|
|||
|
@returns A `Result` containing the value wrapped in `maybe` in an `Ok`,
|
|||
|
or the value generated by `elseFn` in an `Err`.
|
|||
|
*/
|
|||
|
export declare function toOkOrElseErr<T, E>(elseFn: () => E, maybe: Maybe<T>): Result<T, E>;
|
|||
|
export declare function toOkOrElseErr<T, E>(elseFn: () => E): (maybe: Maybe<T>) => Result<T, E>;
|
|||
|
/**
|
|||
|
Construct a `Maybe<T>` from a `Result<T, E>`.
|
|||
|
|
|||
|
If the `Result` is an `Ok`, wrap its value in `Just`. If the `Result` is an
|
|||
|
`Err`, throw away the wrapped `E` and transform to a `Nothing`.
|
|||
|
|
|||
|
@typeparam T The type of the value wrapped in a `Result.Ok` and in the `Just`
|
|||
|
of the resulting `Maybe`.
|
|||
|
@param result The `Result` to construct a `Maybe` from.
|
|||
|
@returns `Just` if `result` was `Ok` or `Nothing` if it was `Err`.
|
|||
|
*/
|
|||
|
export declare function fromResult<T>(result: Result<T, any>): Maybe<T>;
|
|||
|
/**
|
|||
|
Create a `String` representation of a `Maybe` instance.
|
|||
|
|
|||
|
A `Just` instance will be printed as `Just(<representation of the value>)`,
|
|||
|
where the representation of the value is simply the value's own `toString`
|
|||
|
representation. For example:
|
|||
|
|
|||
|
| call | output |
|
|||
|
|----------------------------------------|-------------------------|
|
|||
|
| `toString(Maybe.of(42))` | `Just(42)` |
|
|||
|
| `toString(Maybe.of([1, 2, 3]))` | `Just(1,2,3)` |
|
|||
|
| `toString(Maybe.of({ an: 'object' }))` | `Just([object Object])` |
|
|||
|
| `toString(Maybe.nothing())` | `Nothing` |
|
|||
|
|
|||
|
@typeparam T The type of the wrapped value; its own `.toString` will be used
|
|||
|
to print the interior contents of the `Just` variant.
|
|||
|
@param maybe The value to convert to a string.
|
|||
|
@returns The string representation of the `Maybe`.
|
|||
|
*/
|
|||
|
export declare function toString<T extends {
|
|||
|
toString(): string;
|
|||
|
}>(maybe: Maybe<T>): string;
|
|||
|
/**
|
|||
|
* Create an `Object` representation of a `Maybe` instance.
|
|||
|
*
|
|||
|
* Useful for serialization. `JSON.stringify()` uses it.
|
|||
|
*
|
|||
|
* @param maybe The value to convert to JSON
|
|||
|
* @returns The JSON representation of the `Maybe`
|
|||
|
*/
|
|||
|
export declare function toJSON<T>(maybe: Maybe<T>): MaybeJSON<T>;
|
|||
|
/** A lightweight object defining how to handle each variant of a Maybe. */
|
|||
|
export declare type Matcher<T, A> = {
|
|||
|
Just: (value: T) => A;
|
|||
|
Nothing: () => A;
|
|||
|
};
|
|||
|
/**
|
|||
|
Performs the same basic functionality as `getOrElse`, but instead of simply
|
|||
|
unwrapping the value if it is `Just` and applying a value to generate the same
|
|||
|
default type if it is `Nothing`, lets you supply functions which may transform
|
|||
|
the wrapped type if it is `Just` or get a default value for `Nothing`.
|
|||
|
|
|||
|
This is kind of like a poor man's version of pattern matching, which
|
|||
|
JavaScript currently lacks.
|
|||
|
|
|||
|
Instead of code like this:
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
const logValue = (mightBeANumber: Maybe<number>) => {
|
|||
|
const valueToLog = Maybe.mightBeANumber.isJust()
|
|||
|
? Maybe.unsafelyUnwrap(mightBeANumber).toString()
|
|||
|
: 'Nothing to log.';
|
|||
|
|
|||
|
console.log(valueToLog);
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
...we can write code like this:
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
const logValue = (mightBeANumber: Maybe<number>) => {
|
|||
|
const value = Maybe.match(
|
|||
|
{
|
|||
|
Just: n => n.toString(),
|
|||
|
Nothing: () => 'Nothing to log.',
|
|||
|
},
|
|||
|
mightBeANumber
|
|||
|
);
|
|||
|
|
|||
|
console.log(value);
|
|||
|
};
|
|||
|
```
|
|||
|
|
|||
|
This is slightly longer to write, but clearer: the more complex the resulting
|
|||
|
expression, the hairer it is to understand the ternary. Thus, this is
|
|||
|
especially convenient for times when there is a complex result, e.g. when
|
|||
|
rendering part of a React component inline in JSX/TSX.
|
|||
|
|
|||
|
@param matcher A lightweight object defining what to do in the case of each
|
|||
|
variant.
|
|||
|
@param maybe The `maybe` instance to check.
|
|||
|
*/
|
|||
|
export declare function match<T, A>(matcher: Matcher<T, A>, maybe: Maybe<T>): A;
|
|||
|
export declare function match<T, A>(matcher: Matcher<T, A>): (m: Maybe<T>) => A;
|
|||
|
/** Alias for [`match`](#match) */
|
|||
|
export declare const cata: typeof match;
|
|||
|
/**
|
|||
|
Allows quick triple-equal equality check between the values inside two `maybe`s
|
|||
|
without having to unwrap them first.
|
|||
|
|
|||
|
```ts
|
|||
|
const a = Maybe.of(3);
|
|||
|
const b = Maybe.of(3);
|
|||
|
const c = Maybe.of(null);
|
|||
|
const d = Maybe.nothing();
|
|||
|
|
|||
|
Maybe.equals(a, b); // true
|
|||
|
Maybe.equals(a, c); // false
|
|||
|
Maybe.equals(c, d); // true
|
|||
|
```
|
|||
|
|
|||
|
@param mb A `maybe` to compare to.
|
|||
|
@param ma A `maybe` instance to check.
|
|||
|
*/
|
|||
|
export declare function equals<T>(mb: Maybe<T>, ma: Maybe<T>): boolean;
|
|||
|
export declare function equals<T>(mb: Maybe<T>): (ma: Maybe<T>) => boolean;
|
|||
|
/**
|
|||
|
Allows you to *apply* (thus `ap`) a value to a function without having to
|
|||
|
take either out of the context of their `Maybe`s. This does mean that the
|
|||
|
transforming function is itself within a `Maybe`, which can be hard to grok
|
|||
|
at first but lets you do some very elegant things. For example, `ap` allows
|
|||
|
you to this:
|
|||
|
|
|||
|
```ts
|
|||
|
import { just, nothing } from 'true-myth/maybe';
|
|||
|
|
|||
|
const one = just(1);
|
|||
|
const five = just(5);
|
|||
|
const none = nothing();
|
|||
|
|
|||
|
const add = (a: number) => (b: number) => a + b;
|
|||
|
const maybeAdd = just(add);
|
|||
|
|
|||
|
maybeAdd.ap(one).ap(five); // Just(6)
|
|||
|
maybeAdd.ap(one).ap(none); // Nothing
|
|||
|
maybeAdd.ap(none).ap(five) // Nothing
|
|||
|
```
|
|||
|
|
|||
|
Without `Maybe.ap`, you'd need to do something like a nested `Maybe.match`:
|
|||
|
|
|||
|
```ts
|
|||
|
import { just, nothing } from 'true-myth/maybe';
|
|||
|
|
|||
|
const one = just(1);
|
|||
|
const five = just(5);
|
|||
|
const none = nothing();
|
|||
|
|
|||
|
one.match({
|
|||
|
Just: n => five.match({
|
|||
|
Just: o => just(n + o),
|
|||
|
Nothing: () => nothing(),
|
|||
|
}),
|
|||
|
Nothing: () => nothing(),
|
|||
|
}); // Just(6)
|
|||
|
|
|||
|
one.match({
|
|||
|
Just: n => none.match({
|
|||
|
Just: o => just(n + o),
|
|||
|
Nothing: () => nothing(),
|
|||
|
}),
|
|||
|
Nothing: () => nothing(),
|
|||
|
}); // Nothing
|
|||
|
|
|||
|
none.match({
|
|||
|
Just: n => five.match({
|
|||
|
Just: o => just(n + o),
|
|||
|
Nothing: () => nothing(),
|
|||
|
}),
|
|||
|
Nothing: () => nothing(),
|
|||
|
}); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
And this kind of thing comes up quite often once you're using `Maybe` to
|
|||
|
handle optionality throughout your application.
|
|||
|
|
|||
|
For another example, imagine you need to compare the equality of two
|
|||
|
ImmutableJS data structures, where a `===` comparison won't work. With `ap`,
|
|||
|
that's as simple as this:
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
import Immutable from 'immutable';
|
|||
|
import { curry } from 'lodash'
|
|||
|
|
|||
|
const is = curry(Immutable.is);
|
|||
|
|
|||
|
const x = Maybe.of(Immutable.Set.of(1, 2, 3));
|
|||
|
const y = Maybe.of(Immutable.Set.of(2, 3, 4));
|
|||
|
|
|||
|
Maybe.of(is).ap(x).ap(y); // Just(false)
|
|||
|
```
|
|||
|
|
|||
|
Without `ap`, we're back to that gnarly nested `match`:
|
|||
|
|
|||
|
```ts
|
|||
|
* import Maybe, { just, nothing } from 'true-myth/maybe';
|
|||
|
import Immutable from 'immutable';
|
|||
|
import { curry } from 'lodash'
|
|||
|
|
|||
|
const is = curry(Immutable.is);
|
|||
|
|
|||
|
const x = Maybe.of(Immutable.Set.of(1, 2, 3));
|
|||
|
const y = Maybe.of(Immutable.Set.of(2, 3, 4));
|
|||
|
|
|||
|
x.match({
|
|||
|
Just: iX => y.match({
|
|||
|
Just: iY => Maybe.just(Immutable.is(iX, iY)),
|
|||
|
Nothing: () => Maybe.nothing(),
|
|||
|
})
|
|||
|
Nothing: () => Maybe.nothing(),
|
|||
|
}); // Just(false)
|
|||
|
```
|
|||
|
|
|||
|
In summary: anywhere you have two `Maybe` instances and need to perform an
|
|||
|
operation that uses both of them, `ap` is your friend.
|
|||
|
|
|||
|
Two things to note, both regarding *currying*:
|
|||
|
|
|||
|
1. All functions passed to `ap` must be curried. That is, they must be of the
|
|||
|
form (for add) `(a: number) => (b: number) => a + b`, *not* the more usual
|
|||
|
`(a: number, b: number) => a + b` you see in JavaScript more generally.
|
|||
|
|
|||
|
For convenience, you may want to look at Lodash's `_.curry` or Ramda's
|
|||
|
`R.curry`, which allow you to create curried versions of functions
|
|||
|
whenever you want:
|
|||
|
|
|||
|
```
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
import { curry } from 'lodash';
|
|||
|
|
|||
|
const normalAdd = (a: number, b: number) => a + b;
|
|||
|
const curriedAdd = curry(normalAdd); // (a: number) => (b: number) => a + b;
|
|||
|
|
|||
|
Maybe.of(curriedAdd).ap(Maybe.of(1)).ap(Maybe.of(5)); // Just(6)
|
|||
|
```
|
|||
|
|
|||
|
2. You will need to call `ap` as many times as there are arguments to the
|
|||
|
function you're dealing with. So in the case of `add`, which has the
|
|||
|
"arity" (function argument count) of 2 (`a` and `b`), you'll need to call
|
|||
|
`ap` twice: once for `a`, and once for `b`. To see why, let's look at what
|
|||
|
the result in each phase is:
|
|||
|
|
|||
|
```ts
|
|||
|
const add = (a: number) => (b: number) => a + b;
|
|||
|
|
|||
|
const maybeAdd = Maybe.of(add); // Just((a: number) => (b: number) => a + b)
|
|||
|
const maybeAdd1 = maybeAdd.ap(Maybe.of(1)); // Just((b: number) => 1 + b)
|
|||
|
const final = maybeAdd1.ap(Maybe.of(3)); // Just(4)
|
|||
|
```
|
|||
|
|
|||
|
So for `toString`, which just takes a single argument, you would only need
|
|||
|
to call `ap` once.
|
|||
|
|
|||
|
```ts
|
|||
|
const toStr = (v: { toString(): string }) => v.toString();
|
|||
|
Maybe.of(toStr).ap(12); // Just("12")
|
|||
|
```
|
|||
|
|
|||
|
One other scenario which doesn't come up *quite* as often but is conceivable
|
|||
|
is where you have something that may or may not actually construct a function
|
|||
|
for handling a specific `Maybe` scenario. In that case, you can wrap the
|
|||
|
possibly-present in `ap` and then wrap the values to apply to the function to
|
|||
|
in `Maybe` themselves.
|
|||
|
|
|||
|
**Aside:** `ap` is not named `apply` because of the overlap with JavaScript's
|
|||
|
existing [`apply`] function – and although strictly speaking, there isn't any
|
|||
|
direct overlap (`Maybe.apply` and `Function.prototype.apply` don't intersect
|
|||
|
at all) it's useful to have a different name to avoid implying that they're
|
|||
|
the same.
|
|||
|
|
|||
|
[`apply`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
|
|||
|
|
|||
|
@param maybeFn maybe a function from T to U
|
|||
|
@param maybe maybe a T to apply to `fn`
|
|||
|
*/
|
|||
|
export declare function ap<T, U>(maybeFn: Maybe<(t: T) => U>, maybe: Maybe<T>): Maybe<U>;
|
|||
|
export declare function ap<T, U>(maybeFn: Maybe<(t: T) => U>): (maybe: Maybe<T>) => Maybe<U>;
|
|||
|
/**
|
|||
|
Determine whether an item is an instance of `Just` or `Nothing`.
|
|||
|
|
|||
|
@param item The item to check.
|
|||
|
*/
|
|||
|
export declare function isInstance<T = any>(item: any): item is Maybe<T>;
|
|||
|
declare type Predicate<T> = (element: T, index: number, array: T[]) => boolean;
|
|||
|
/**
|
|||
|
Safely search for an element in an array.
|
|||
|
|
|||
|
This function behaves like `Array.prototype.find`, but returns `Maybe<T>`
|
|||
|
instead of `T | undefined`.
|
|||
|
|
|||
|
## Examples
|
|||
|
|
|||
|
The basic form is:
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
let array = [1, 2, 3];
|
|||
|
Maybe.find(v => v > 1, array); // Just(2)
|
|||
|
Maybe.find(v => v < 1, array); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
The function is curried so you can use it in a functional chain. For example
|
|||
|
(leaving aside error handling on a bad response for simplicity), suppose the
|
|||
|
url `https://arrays.example.com` returned a JSON payload with the type
|
|||
|
`Array<{ count: number, name: string }>`, and we wanted to get the first
|
|||
|
of these where `count` was at least 100. We could write this:
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
type Item = { count: number; name: string };
|
|||
|
type Response = Array<Item>;
|
|||
|
|
|||
|
// curried variant!
|
|||
|
const findAtLeast100 = Maybe.find(({ count }: Item) => count > 100);
|
|||
|
|
|||
|
fetch('https://arrays.example.com')
|
|||
|
.then(response => response.json() as Response)
|
|||
|
.then(findAtLeast100)
|
|||
|
.then(found => {
|
|||
|
if (found.isJust()) {
|
|||
|
console.log(`The matching value is ${found.value.name}!`);
|
|||
|
}
|
|||
|
});
|
|||
|
```
|
|||
|
|
|||
|
@param predicate A function to execute on each value in the array, returning
|
|||
|
`true` when the item in the array matches the condition. The
|
|||
|
signature for `predicate` is identical to the signature for
|
|||
|
the first argument to `Array.prototype.find`. The function
|
|||
|
is called once for each element of the array, in ascending
|
|||
|
order, until it finds one where predicate returns true. If
|
|||
|
such an element is found, find immediately returns that
|
|||
|
element value wrapped in `Just`. Otherwise, `Maybe.find`
|
|||
|
returns `Nothing`.
|
|||
|
* @param array The array to search using the predicate.
|
|||
|
*/
|
|||
|
export declare function find<T>(predicate: Predicate<T>, array: T[]): Maybe<T>;
|
|||
|
export declare function find<T>(predicate: Predicate<T>): (array: T[]) => Maybe<T>;
|
|||
|
/**
|
|||
|
Safely get the first item from a list, returning `Just` the first item if the
|
|||
|
array has at least one item in it, or `Nothing` if it is empty.
|
|||
|
|
|||
|
## Examples
|
|||
|
|
|||
|
```ts
|
|||
|
let empty = [];
|
|||
|
Maybe.head(empty); // => Nothing
|
|||
|
|
|||
|
let full = [1, 2, 3];
|
|||
|
Maybe.head(full); // => Just(1)
|
|||
|
```
|
|||
|
|
|||
|
@param array The array to get the first item from.
|
|||
|
*/
|
|||
|
export declare function head<T>(array: Array<T | null | undefined>): Maybe<T>;
|
|||
|
/** A convenience alias for `Maybe.head`. */
|
|||
|
export declare const first: typeof head;
|
|||
|
/**
|
|||
|
Safely get the last item from a list, returning `Just` the last item if the
|
|||
|
array has at least one item in it, or `Nothing` if it is empty.
|
|||
|
|
|||
|
## Examples
|
|||
|
|
|||
|
```ts
|
|||
|
let empty = [];
|
|||
|
Maybe.last(empty); // => Nothing
|
|||
|
|
|||
|
let full = [1, 2, 3];
|
|||
|
Maybe.last(full); // => Just(3)
|
|||
|
```
|
|||
|
|
|||
|
@param array The array to get the first item from.
|
|||
|
*/
|
|||
|
export declare function last<T>(array: Array<T | null | undefined>): Maybe<T>;
|
|||
|
/**
|
|||
|
Convert the arguments to a single `Maybe`. Useful for dealing with arrays of
|
|||
|
`Maybe`s, via the spread operator.
|
|||
|
|
|||
|
## Examples
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
let valid = [Maybe.just(2), Maybe.just('three')];
|
|||
|
Maybe.all(...valid); // => Just([2, 'three']);
|
|||
|
|
|||
|
let invalid = [Maybe.just(2), Maybe.nothing<string>()];
|
|||
|
Maybe.all(...invalid); // => Nothing
|
|||
|
```
|
|||
|
|
|||
|
## Note on Spread
|
|||
|
|
|||
|
This requires the use of the spread operator because (at least as of
|
|||
|
TypeScript 3.0), the type inference falls down when attempting to build this
|
|||
|
same type with an array directly. Moreover, this spread-based approach handles
|
|||
|
heteregenous arrays; TS *also* fails to infer correctly for anything but
|
|||
|
homogeneous arrays when using that approach.
|
|||
|
|
|||
|
@param maybes The `Maybe`s to resolve to a single `Maybe`.
|
|||
|
*/
|
|||
|
export declare function all<T extends Array<Maybe<any>>>(...maybes: T): All<T>;
|
|||
|
declare type All<T extends Array<Maybe<any>>> = T extends Array<Maybe<infer U>> ? Maybe<Array<U>> : never;
|
|||
|
/**
|
|||
|
Given a tuple of `Maybe`s, return a `Maybe` of the tuple values.
|
|||
|
|
|||
|
Given a tuple of type `[Maybe<A>, Maybe<B>]`, the resulting type is
|
|||
|
`Maybe<[A, B]>`. Works with up to a 5-tuple. (If you're doing more than a
|
|||
|
5-tuple, what are you doing???)
|
|||
|
|
|||
|
## Examples
|
|||
|
|
|||
|
If any of the items in the tuple are `Nothing`, the whole result is `Nothing`.
|
|||
|
Here, for example, `result` has the type `Maybe<[string, number]>` and will be
|
|||
|
`Nothing`:
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
type Tuple = [Maybe<string>, Maybe<number>];
|
|||
|
|
|||
|
let invalid: Tuple = [Maybe.just('wat'), Maybe.nothing()];
|
|||
|
let result = Maybe.tuple(invalid); // => Nothing
|
|||
|
```
|
|||
|
|
|||
|
If all of the items in the tuple are `Just`, the result is `Just` wrapping the
|
|||
|
tuple of the values of the items. Here, for example, `result` again has the
|
|||
|
type `Maybe<[string, number]>` and will be `Just(['hey', 12]`:
|
|||
|
|
|||
|
```ts
|
|||
|
import Maybe from 'true-myth/maybe';
|
|||
|
|
|||
|
type Tuple = [Maybe<string>, Maybe<number>];
|
|||
|
|
|||
|
let valid: Tuple = [Maybe.just('hey'), Maybe.just(12)];
|
|||
|
let result = Maybe.tuple(valid); // => Just(['hey', 12])
|
|||
|
```
|
|||
|
|
|||
|
@param maybes: the tuple of `Maybe`s to convert to a `Maybe` of tuple values.
|
|||
|
*/
|
|||
|
export declare function tuple<T>(maybes: [Maybe<T>]): Maybe<[T]>;
|
|||
|
export declare function tuple<T, U>(maybes: [Maybe<T>, Maybe<U>]): Maybe<[T, U]>;
|
|||
|
export declare function tuple<T, U, V>(maybes: [Maybe<T>, Maybe<U>, Maybe<V>]): Maybe<[T, U, V]>;
|
|||
|
export declare function tuple<T, U, V, W>(maybes: [Maybe<T>, Maybe<U>, Maybe<V>, Maybe<W>]): Maybe<[T, U, V, W]>;
|
|||
|
/**
|
|||
|
Safely extract a key from an object, returning `Just` if the key has a value
|
|||
|
on the object and `Nothing` if it does not.
|
|||
|
|
|||
|
The check is type-safe: you won't even be able to compile if you try to look
|
|||
|
up a property that TypeScript *knows* doesn't exist on the object.
|
|||
|
|
|||
|
```ts
|
|||
|
type Person = { name?: string };
|
|||
|
|
|||
|
const me: Person = { name: 'Chris' };
|
|||
|
console.log(Maybe.property('name', me)); // Just('Chris')
|
|||
|
|
|||
|
const nobody: Person = {};
|
|||
|
console.log(Maybe.property('name', nobody)); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
However, it also works correctly with dictionary types:
|
|||
|
|
|||
|
```ts
|
|||
|
type Dict<T> = { [key: string]: T };
|
|||
|
|
|||
|
const score: Dict<number> = {
|
|||
|
player1: 0,
|
|||
|
player2: 1
|
|||
|
};
|
|||
|
|
|||
|
console.log(Maybe.property('player1', score)); // Just(0)
|
|||
|
console.log(Maybe.property('player2', score)); // Just(1)
|
|||
|
console.log(Maybe.property('player3', score)); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
The order of keys is so that it can be partially applied:
|
|||
|
|
|||
|
```ts
|
|||
|
type Person = { name?: string };
|
|||
|
|
|||
|
const lookupName = Maybe.property('name');
|
|||
|
|
|||
|
const me: Person = { name: 'Chris' };
|
|||
|
console.log(lookupName(me)); // Just('Chris')
|
|||
|
|
|||
|
const nobody: Person = {};
|
|||
|
console.log(lookupName(nobody)); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
@param key The key to pull out of the object.
|
|||
|
@param obj The object to look up the key from.
|
|||
|
*/
|
|||
|
export declare function property<T, K extends keyof T>(key: K, obj: T): Maybe<NonNullable<T[K]>>;
|
|||
|
export declare function property<T, K extends keyof T>(key: K): (obj: T) => Maybe<NonNullable<T[K]>>;
|
|||
|
/**
|
|||
|
Safely extract a key from a Maybe of an object, returning `Just` if the key
|
|||
|
has a value on the object and `Nothing` if it does not. (Like `Maybe.property`
|
|||
|
but operating on a `Maybe<T>` rather than directly on a `T`.)
|
|||
|
|
|||
|
The check is type-safe: you won't even be able to compile if you try to look
|
|||
|
up a property that TypeScript *knows* doesn't exist on the object.
|
|||
|
|
|||
|
```ts
|
|||
|
type Person = { name?: string };
|
|||
|
|
|||
|
const me: Maybe<Person> = Maybe.just({ name: 'Chris' });
|
|||
|
console.log(Maybe.get('name', me)); // Just('Chris')
|
|||
|
|
|||
|
const nobody = Maybe.nothing<Person>();
|
|||
|
console.log(Maybe.get('name', nobody)); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
However, it also works correctly with dictionary types:
|
|||
|
|
|||
|
```ts
|
|||
|
type Dict<T> = { [key: string]: T };
|
|||
|
|
|||
|
const score: Maybe<Dict<number>> = Maybe.just({
|
|||
|
player1: 0,
|
|||
|
player2: 1
|
|||
|
});
|
|||
|
|
|||
|
console.log(Maybe.get('player1', score)); // Just(0)
|
|||
|
console.log(Maybe.get('player2', score)); // Just(1)
|
|||
|
console.log(Maybe.get('player3', score)); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
The order of keys is so that it can be partially applied:
|
|||
|
|
|||
|
```ts
|
|||
|
type Person = { name?: string };
|
|||
|
|
|||
|
const lookupName = Maybe.get('name');
|
|||
|
|
|||
|
const me: Person = { name: 'Chris' };
|
|||
|
console.log(lookupName(me)); // Just('Chris')
|
|||
|
|
|||
|
const nobody: Person = {};
|
|||
|
console.log(lookupName(nobody)); // Nothing
|
|||
|
```
|
|||
|
|
|||
|
@param key The key to pull out of the object.
|
|||
|
@param obj The object to look up the key from.
|
|||
|
*/
|
|||
|
export declare function get<T, K extends keyof T>(key: K, maybeObj: Maybe<T>): Maybe<T[K]>;
|
|||
|
export declare function get<T, K extends keyof T>(key: K): (maybeObj: Maybe<T>) => Maybe<T[K]>;
|
|||
|
/**
|
|||
|
Transform a function from a normal JS function which may return `null` or
|
|||
|
`undefined` to a function which returns a `Maybe` instead.
|
|||
|
|
|||
|
For example, dealing with the `Document#querySelector` DOM API involves a
|
|||
|
*lot* of things which can be `null`:
|
|||
|
|
|||
|
```ts
|
|||
|
const foo = document.querySelector('#foo');
|
|||
|
let width: number;
|
|||
|
if (foo !== null) {
|
|||
|
width = foo.getBoundingClientRect().width;
|
|||
|
} else {
|
|||
|
width = 0;
|
|||
|
}
|
|||
|
|
|||
|
const getStyle = (el: HTMLElement, rule: string) => el.style[rule];
|
|||
|
const bar = document.querySelector('.bar');
|
|||
|
let color: string;
|
|||
|
if (bar != null) {
|
|||
|
let possibleColor = getStyle(bar, 'color');
|
|||
|
if (possibleColor !== null) {
|
|||
|
color = possibleColor;
|
|||
|
} else {
|
|||
|
color = 'black';
|
|||
|
}
|
|||
|
}
|
|||
|
```
|
|||
|
|
|||
|
(Imagine in this example that there were more than two options: the
|
|||
|
simplifying workarounds you commonly use to make this terser in JS, like the
|
|||
|
ternary operator or the short-circuiting `||` operator, eventually become very
|
|||
|
confusing with more complicated flows.)
|
|||
|
|
|||
|
We can work around this with `Maybe`, always wrapping each layer in `Maybe.of`
|
|||
|
invocations, and this is *somewhat* better:
|
|||
|
|
|||
|
```ts
|
|||
|
const aWidth = Maybe.of(document.querySelector('#foo'))
|
|||
|
.map(el => el.getBoundingClientRect().width)
|
|||
|
.unwrapOr(0);
|
|||
|
|
|||
|
const aColor = Maybe.of(document.querySelector('.bar'))
|
|||
|
.andThen(el => Maybe.of(getStyle(el, 'color'))
|
|||
|
.unwrapOr('black');
|
|||
|
```
|
|||
|
|
|||
|
With `wrapReturn`, though, you can create a transformed version of a function
|
|||
|
*once* and then be able to use it freely throughout your codebase, *always*
|
|||
|
getting back a `Maybe`:
|
|||
|
|
|||
|
```ts
|
|||
|
const querySelector = Maybe.wrapReturn(document.querySelector.bind(document));
|
|||
|
const safelyGetStyle = Maybe.wrapReturn(getStyle);
|
|||
|
|
|||
|
const aWidth = querySelector('#foo')
|
|||
|
.map(el => el.getBoundingClientRect().width)
|
|||
|
.unwrapOr(0);
|
|||
|
|
|||
|
const aColor = querySelector('.bar')
|
|||
|
.andThen(el => safelyGetStyle(el, 'color'))
|
|||
|
.unwrapOr('black');
|
|||
|
```
|
|||
|
|
|||
|
@param fn The function to transform; the resulting function will have the
|
|||
|
exact same signature except for its return type.
|
|||
|
*/
|
|||
|
export declare function wrapReturn<F extends (...args: any[]) => any>(fn: F): (...args: Parameters<F>) => Maybe<NonNullable<ReturnType<F>>>;
|
|||
|
/** Alias for [`wrapReturn`](#wrapReturn). */
|
|||
|
export declare const maybeify: typeof wrapReturn;
|
|||
|
export declare const transmogrify: typeof wrapReturn;
|
|||
|
/** A value which may (`Just<T>`) or may not (`Nothing`) be present. */
|
|||
|
export declare type Maybe<T> = Just<T> | Nothing<T>;
|
|||
|
export declare const Maybe: {
|
|||
|
Variant: typeof Variant;
|
|||
|
Just: typeof Just;
|
|||
|
Nothing: typeof Nothing;
|
|||
|
all: typeof all;
|
|||
|
isJust: typeof isJust;
|
|||
|
isNothing: typeof isNothing;
|
|||
|
just: typeof just;
|
|||
|
nothing: typeof nothing;
|
|||
|
of: typeof of;
|
|||
|
find: typeof find;
|
|||
|
first: typeof head;
|
|||
|
fromNullable: typeof of;
|
|||
|
head: typeof head;
|
|||
|
last: typeof last;
|
|||
|
map: typeof map;
|
|||
|
mapOr: typeof mapOr;
|
|||
|
mapOrElse: typeof mapOrElse;
|
|||
|
and: typeof and;
|
|||
|
andThen: typeof andThen;
|
|||
|
chain: typeof andThen;
|
|||
|
flatMap: typeof andThen;
|
|||
|
or: typeof or;
|
|||
|
orElse: typeof orElse;
|
|||
|
unsafelyUnwrap: typeof unsafelyUnwrap;
|
|||
|
unsafelyGet: typeof unsafelyUnwrap;
|
|||
|
unsafeGet: typeof unsafelyUnwrap;
|
|||
|
unwrapOr: typeof unwrapOr;
|
|||
|
getOr: typeof unwrapOr;
|
|||
|
unwrapOrElse: typeof unwrapOrElse;
|
|||
|
getOrElse: typeof unwrapOrElse;
|
|||
|
toOkOrErr: typeof toOkOrErr;
|
|||
|
toOkOrElseErr: typeof toOkOrElseErr;
|
|||
|
fromResult: typeof fromResult;
|
|||
|
toString: typeof toString;
|
|||
|
toJSON: typeof toJSON;
|
|||
|
tuple: typeof tuple;
|
|||
|
match: typeof match;
|
|||
|
cata: typeof match;
|
|||
|
equals: typeof equals;
|
|||
|
ap: typeof ap;
|
|||
|
isInstance: typeof isInstance;
|
|||
|
property: typeof property;
|
|||
|
get: typeof get;
|
|||
|
wrapReturn: typeof wrapReturn;
|
|||
|
ify: typeof wrapReturn;
|
|||
|
};
|
|||
|
export default Maybe;
|
|||
|
//# sourceMappingURL=maybe.d.ts.map
|