Skip to content

Instantly share code, notes, and snippets.

@VitorLuizC
Forked from kimamula/Optional.ts
Last active March 5, 2019 01:34
Show Gist options
  • Save VitorLuizC/d893b4f6b2802e68691044083a0aa7f6 to your computer and use it in GitHub Desktop.
Save VitorLuizC/d893b4f6b2802e68691044083a0aa7f6 to your computer and use it in GitHub Desktop.
Implementation of Maybe (Optional) in TypeScript.
type None = void | null | undefined;
const isNone = (value: unknown): value is None => {
return value === null || typeof value === 'undefined';
};
const isMaybe = (value: unknown): value is Maybe<any> => {
return !!(value && (value as { _isMaybe?: any })._isMaybe);
};
type MaybePattern<T, U> = {
none: () => U;
some: (value: T) => U;
};
type Maybe<T> = {
_isMaybe: true,
get: (placeholder: T) => T;
map: <U>(fn: (value: T) => U) => Maybe<U>;
match: <U>(pattern: MaybePattern<T, U>) => U;
unwrap: () => T | None;
};
const None = <T>(): Maybe<T> => ({
_isMaybe: true,
get: (placeholder) => placeholder,
map: () => None(),
match: (pattern) => pattern.none(),
unwrap: () => undefined,
});
const Some = <T>(value: T): Maybe<T> => {
if (isNone(value))
throw new Error('Value is not some.');
return {
_isMaybe: true,
get: () => value,
map: (fn) => {
const _value = fn(value);
return isMaybe(_value) ? _value : Maybe(_value);
},
match: (pattern) => pattern.some(value),
unwrap: () => value,
};
};
const Maybe = <T>(value: T | None): Maybe<T> => {
return isNone(value) ? None<T>() : Some<T>(value);
};
export { isNone, None, Some, isMaybe, Maybe, MaybePattern };
export default Maybe;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment