UNPKG

@snipsonian/core

Version:

Core/base reusable javascript code snippets

66 lines (53 loc) 1.94 kB
/* eslint-disable max-len */ /** * Inspired by: * - https://codewithstyle.info/advanced-functional-programming-in-typescript-maybe-monad/ * - https://medium.com/@yyankowski/maybe-monad-in-javascript-to-save-us-from-the-hell-of-the-null-guard-clauses-bc9f9a1f291b */ /* eslint-enable max-len */ import isNull from '../is/isNull'; import isUndefined from '../is/isUndefined'; import { TEmptyObject } from '../typings/object'; export class Maybe<Value> { private readonly value: Value | null | undefined; private constructor(value: Value | null | undefined) { this.value = value; } public static of<Value>(value: Value | null | undefined): Maybe<Value> { return new Maybe(value); } public static nothing<Value>(): Maybe<Value> { return new Maybe<Value>(null); } public isNothing(): boolean { return isNull(this.value) || isUndefined(this.value); } public map<ResultValue>(mapper: (prevValue: Value) => ResultValue): Maybe<ResultValue> { return this.isNothing() ? Maybe.nothing() : Maybe.of(mapper(this.value)); } /** * Use - instead of 'map' - if the mapper function returns a Maybe. * (The 'map' function would otherwise result in a Maybe of a Maybe) */ public flatMap<ResultValue>(mapper: (prevValue: Value) => Maybe<ResultValue>): Maybe<ResultValue> { return this.isNothing() ? Maybe.nothing() : mapper(this.value); } public getOrElse(elseValue: Value): Value { return this.isNothing() ? elseValue : this.value; } public getOrNull(): Value | null { return this.getOrElse(null); } public getOrEmptyArray(): Value | [] { return this.getOrElse([] as unknown as Value); } public getOrEmptyObject(): Value | TEmptyObject { return this.getOrElse({} as unknown as Value); } }