UNPKG

@sanjagh/option

Version:

Out of the box solution for writing null-safe javascript

195 lines (140 loc) 3.23 kB
// @flow export interface Option<+T> { /* eslint-disable no-undef */ isDefined(): boolean; isEmpty(): boolean; get(): T; getOrElse<U>(U): T | U; default<U>(U): T | U; getOrNull(): T | null; getOrUndefined(): T | void; map<U>((T) => U): Option<U>; filter((T) => boolean): Option<T>; reject((T) => boolean): Option<T>; bind<U>((T) => Option<U>): Option<U>; flatMap<U>((T) => Option<U>): Option<U>; fold<U>(U, (T) => U): U; foldLeft<U>(U, (U, T) => U): U; foldRight<U>(U, (T, U) => U): U; forEach((T) => void): void; /* eslint-enable */ } class None implements Option<empty> { isDefined(): boolean { return false; } isEmpty(): boolean { return true; } get() { throw new Error('NO VALUE'); } getOrElse<U>(defaultValue: U): U { return defaultValue; } default<U>(defaultValue: U): U { return this.getOrElse(defaultValue); } getOrNull(): null { return null; } getOrUndefined(): void { return undefined; } map<U>(_m: (any) => U): None { return new None(); } filter(_p: (any) => boolean): None { return new None(); } reject(_p: (any) => boolean): None { return new None(); } bind<U>(_m: (any) => Option<U>): None { return new None(); } flatMap<U>(m: (any) => Option<U>): None { return this.bind(m); } fold<U>(initialValue: U, f: (any) => U): U { return this.map(f).getOrElse(initialValue); } foldLeft<U>(initialValue: U, _f: (U, any) => U): U { return initialValue; } foldRight<U>(initialValue: U, _f: (any, U) => U): U { return initialValue; } forEach(_f: any): void {} } class Some<T> implements Option<T> { value: T; constructor(value: T) { this.value = value; } isDefined(): boolean { return true; } isEmpty(): boolean { return false; } get(): T { return this.value; } getOrElse<U>(_defaultValue: U): T { return this.get(); } default<U>(_defaultValue: U): T { return this.getOrElse(); } getOrNull(): T { return this.get(); } getOrUndefined(): T { return this.get(); } map<U>(m: (T) => U): Some<U> { return new Some(m(this.get())); } filter(p: (T) => boolean): Option<T> { return p(this.get()) ? new Some(this.get()) : new None(); } reject(p: (T) => boolean): Option<T> { return this.filter((x: T) => !p(x)); } bind<U>(m: (T) => Option<U>): Option<U> { return m(this.get()); } flatMap<U>(m: (T) => Option<U>): Option<U> { return this.bind(m); } fold<U>(initialValue: U, f: (T) => U): U { return this.map(f).getOrElse(initialValue); } foldLeft<U>(initialValue: U, f: (U, T) => U): U { return f(initialValue, this.get()); } foldRight<U>(initialValue: U, f: (T, U) => U): U { return f(this.get(), initialValue); } forEach(f: (T) => void): void { f(this.get()); } } function none(): None { return new None(); } function some<T>(value: T): Some<T> { return new Some(value); } function option<T>(value: ?T): Option<T> { return value == null ? none() : some(value); } const Opt = { None, Some, none, some, option, }; export { None, Some, none, some, option, Opt as default };