// // Options (inspired by rust) // // Most methods like `document.getElementById("something")` will naturally return something of the type `Option` // This type has been chosen to remain compatible with most vanilla JS methods. // A more capable option type could have been made by creating an option object, but would lose compatibility with JS. export type Option = null | undefined | T; export function isNone(input: Option): boolean { if (input === null || input === undefined) { return true; } return false; } export function isSome(input: Option): boolean { if (input === null || input === undefined) { return false; } return true; } type SingleArgCallback = (v: T) => void; type EmptyCallback = () => void; /** * If the input `Option` is some, then run the `doAfter` callback. * Intended to mimic rust's conditional enum matching pattern: `if let Some(v) = opt {}` */ export function ifSome( input: Option, doAfter: SingleArgCallback ): void { if (isSome(input)) { doAfter(input as T); } } export function ifNone(input: Option, doAfter: EmptyCallback): void { if (isNone(input)) { doAfter(); } } // Not sure how ergonomic this is in actual use. It may get axed. export function ifEither( input: Option, doIfSome: SingleArgCallback, doIfNone: EmptyCallback ): void { if (isSome(input)) { doIfSome(input as T); return; } doIfNone(); } /** Unwrap option of `null|undefined|T` to `T` throw error if value is not `T`. `expect()` is preferred to this function as it gives better error messages */ export function unwrap(input: Option): T { if (isNone(input)) { throw new TypeError("Unwrap called on null/undefined value"); } return input as T; } /** Unwrap option of `null|undefined|T` to `T` throw error with `exceptionMessage` if value is not `T` */ export function expect(input: Option, exceptionMessage: string): T { if (isNone(input)) { throw new TypeError(exceptionMessage); } return input as T; }