Skip to content

Commit

Permalink
feat(errors): add ensureXXX() functions
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Jul 25, 2023
1 parent 88cfe77 commit be70868
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/errors/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@
"./deferror": {
"default": "./deferror.js"
},
"./ensure": {
"default": "./ensure.js"
},
"./illegal-arguments": {
"default": "./illegal-arguments.js"
},
Expand Down
150 changes: 150 additions & 0 deletions packages/errors/src/ensure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import { assert } from "./assert.js";

/**
* Higher-order function to define ensurance assertions. Takes a `pred`icate
* function and an `expected` (type) name, returns a new function which accepts
* 2 args (an arbitrary value `x` and optional error `msg`). When called, checks
* `x` for non-null and if so applies given `pred`icate. If result is false (or
* `x` is nullish) and iff {@link assert} is enabled, throws a
* {@link AssertionError} with given `msg` (or a constructed default msg).
* Otherwise function is a no-op.
*
* @param pred
* @param expected
*/
export const defEnsure =
<T>(pred: (x: any) => boolean, expected: string) =>
(x: any, msg?: string) => {
x != null
? assert(
() => pred(x),
msg || `expected ${expected}, got ${typeof x}`
)
: assert(false, `expected ${expected}, got ${x}`);
return <T>x;
};

/**
* Only enabled if {@link assert} is enabled (otherwise no-op). Checks if `x` is
* a JS array and if not throws {@link AssertionError}, optionally with given
* `msg`.
*
* @remarks
* See {@link defEnsure} for details.
*
* @param x
* @param msg
*/
export const ensureArray = defEnsure<any[]>((x) => Array.isArray(x), `array`);

/**
* Only enabled if {@link assert} is enabled (otherwise no-op). Checks if `x` is
* a bigint and if not throws {@link AssertionError}, optionally with given
* `msg`.
*
* @remarks
* See {@link defEnsure} for details.
*
* @param x
* @param msg
*/
export const ensureBigInt = defEnsure<bigint>(
(x) => typeof x === "bigint",
"bigint"
);

/**
* Only enabled if {@link assert} is enabled (otherwise no-op). Checks if `x` is
* a boolean and if not throws {@link AssertionError}, optionally with given
* `msg`.
*
* @remarks
* See {@link defEnsure} for details.
*
* @param x
* @param msg
*/
export const ensureBoolean = defEnsure<boolean>(
(x) => typeof x === "boolean",
"boolean"
);

/**
* Only enabled if {@link assert} is enabled (otherwise no-op). Checks if `x` is
* a function and if not throws {@link AssertionError}, optionally with given
* `msg`.
*
* @remarks
* See {@link defEnsure} for details.
*
* @param x
* @param msg
*/
export const ensureFunction = defEnsure<Function>(
(x) => typeof x === "function",
"function"
);

/**
* Only enabled if {@link assert} is enabled (otherwise no-op). Checks if `x` is
* an ES6 iterable and if not throws {@link AssertionError}, optionally with
* given `msg`.
*
* @remarks
* See {@link defEnsure} for details.
*
* @param x
* @param msg
*/
export const ensureIterable = defEnsure<Iterable<any>>(
(x) => typeof x[Symbol.iterator] === "function",
"iterable"
);

/**
* Only enabled if {@link assert} is enabled (otherwise no-op). Checks if `x` is
* a number and if not throws {@link AssertionError}, optionally with given
* `msg`.
*
* @remarks
* See {@link defEnsure} for details.
*
* @param x
* @param msg
*/
export const ensureNumber = defEnsure<number>(
(x) => typeof x === "number",
"number"
);

/**
* Only enabled if {@link assert} is enabled (otherwise no-op). Checks if `x` is
* a string and if not throws {@link AssertionError}, optionally with given
* `msg`.
*
* @remarks
* See {@link defEnsure} for details.
*
* @param x
* @param msg
*/
export const ensureString = defEnsure<string>(
(x) => typeof x === "string",
"string"
);

/**
* Only enabled if {@link assert} is enabled (otherwise no-op). Checks if `x` is
* a symbol and if not throws {@link AssertionError}, optionally with given
* `msg`.
*
* @remarks
* See {@link defEnsure} for details.
*
* @param x
* @param msg
*/
export const ensureSymbol = defEnsure<symbol>(
(x) => typeof x === "symbol",
"symbol"
);
1 change: 1 addition & 0 deletions packages/errors/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export * from "./deferror.js";

export * from "./assert.js";
export * from "./ensure.js";
export * from "./illegal-arguments.js";
export * from "./illegal-arity.js";
export * from "./illegal-state.js";
Expand Down

0 comments on commit be70868

Please sign in to comment.