@rickosborne/guard
TypeScript icon, indicating that this package has built-in type declarations

2025.3.12 • Public • Published

@rickosborne/guard

Basic type guards building on helper types from @rickosborne/typical.

Usage

Install via your favorite package manager.

Each package supports CommonJS require, ESM import, and TypeScript usage.

You also have a choice: barrel imports or direct imports.

Barrel imports mean you're going to require/import everything from the same package-level namespace:

// CommonJS
const { isPlainObject, isListOf } = require("@rickosborne/guard");
// ESM / TypeScript
import { isPlainObject, isListOf } from "@rickosborne/guard";

Implications:

  • Nice and simple.
  • Your build system needs to do tree-shaking well ... or you'll end up adding the entire package even if you only import two functions.

The other option is to use direct imports:

// CommonJS
const { isPlainObject } = require("@rickosborne/guard/is-object");
const { isListOf } = require("@rickosborne/guard/is-list-of");
// ESM / TypeScript
import { isPlainObject } from "@rickosborne/guard/is-object.js";
import { isListOf } from "@rickosborne/guard/is-list-of.js";

Implications:

  • You (probably) don't have to worry about tree-shaking as your build (likely) ends up with only the functions you need.

If you're using a modern build system, there aren't any strong reasons to prefer one way over the other. It's really just down to your personal preference.

A quick note about file extensions

Do you need to use file extensions? And if so, which extensions?

Honestly ... this is a dumpster fire question. It really comes down to your own setup and configuration.

Within each package itself:

  • The CommonJS files all have .cjs extensions.
  • The ESM files all have .mjs extensions.
  • Node subpath exports have been set up to send .js imports to the .cjs (via require) or .mjs (via import) files, depending on your setup.

So, in theory, the only extension which won't work would be .ts because the source isn't included.

If you run into a problem with a particular configuration, file a GitHub issue with:

  • Your tsconfig.json's module, moduleResolution, and target settings.
  • Your package.json's type and imports settings.
  • An example of another package which imports correctly for you.

License

This package is licensed as CC-BY-NC-SA-4.0 unless otherwise noted. That is, Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International.


API

Classes

ValidationError

 class ValidationError extends Error 

An error which collects any number of problems encountered while attempting to validate a value against a type schema/guard.

Functions

assertDefined

 function assertDefined<T>(value: T, messageOrError: MessageOrError): asserts value is NonNullable<T>;

Assert the given value is not null or undefined. Throws with the given message or error, otherwise.

assertInt

 function assertInt(value: unknown, messageOrError: MessageOrError): asserts value is number;

Throw if the given value is not an integer.

assertJSONArray

 function assertJSONArray(value: unknown): asserts value is JSONArray;

Assert the given value could be serialized as a JSON Array.

assertJSONObject

 function assertJSONObject(value: unknown): asserts value is JSONObject;

Assert the given value could be serialized as a JSON Object.

assertJSONPrimitive

 function assertJSONPrimitive(value: unknown): asserts value is JSONPrimitive;

Assert the given value could be serialized as a JSON Primitive.

assertJSONSerializable

 function assertJSONSerializable(value: unknown): asserts value is JSONSerializable;

Assert the given value could be serialized as JSON.

errorFromMessageOrError

errorFromMessageOrError: (messageOrError: MessageOrError, defaultConstructor?: (new (message: string) => Error)) => Error

Helper for guards which expect text or an error, or can generate one when needed.

expectDefined

expectDefined: <T>(obj: T, messageOrError: MessageOrError) => NonNullable<T>

Coerce a value's type to exclude null or undefined, or throw if it actually is null or undefined.

expectInt

expectInt: (obj: unknown, messageOrError: MessageOrError) => number

Coerce a value's type to a number, throwing if it's not an integer.

formatValidationProblem

formatValidationProblem: (problem: ValidationProblem) => string

hasArray

 function hasArray<Name extends string>(obj: unknown, name: Name, predicate?: undefined): obj is {
    [K in Name]: unknown[];
};

Guard for whether the given value is an object which has a property with its own array value. This variant does not exhaustively check the items of the array.

hasArray

 function hasArray<Name extends string, Item>(obj: unknown, name: Name, predicate?: (item: unknown, index: number, items: unknown[]) => item is Item): obj is {
    [K in Name]: Item[];
};

Guard for whether the given value is an object which has a property with its own array value. This variant exhaustively checks the items of the array against the given predicate.

hasNumber

hasNumber: <Name extends string>(obj: unknown, name: Name) => obj is { [k in Name]: number; }

Guard for whether an object has a property with the given name and a numeric value.

hasObject

hasObject: <Name extends string>(obj: unknown, name: Name) => obj is { [k in Name]: object; }

Guard for whether an object has a property with the given name and an object value.

hasOptional

 function hasOptional<Name extends string>(obj: unknown, name: Name): obj is {
    [K in Name]?: unknown;
};

Guard for whether the given value is an object with an optional property with the given name. This variant does not check the value, only that the property exists.

hasOptional

 function hasOptional<Name extends string, T>(obj: unknown, name: Name, predicate: (value: unknown) => value is T): obj is {
    [K in Name]?: T;
};

Guard for whether the given value is an object with an optional property with the given name. This variant checks the value against the given predicate.

hasOwn

 function hasOwn<Name extends string | symbol>(obj: unknown, name: Name): obj is {
    [K in Name]: unknown;
};

Guard for whether the given value is an object with a property with the given name. This variant does not check the value, only that the property exists.

hasOwn

 function hasOwn<Name extends string | symbol, T>(obj: unknown, name: Name, predicate: (value: unknown) => value is T): obj is {
    [K in Name]: T;
};

Guard for whether the given value is an object with a property with the given name. This variant checks the value against the given predicate.

hasPlainObject

hasPlainObject: <Name extends string>(obj: unknown, name: Name) => obj is { [k in Name]: Record<never, never>; }

Guard for whether an object has a property with the given name and a plain object value.

hasString

hasString: <Name extends string>(obj: unknown, name: Name) => obj is { [k in Name]: string; }

Check whether the given value is an object, has a property with the given name, and the value of that property is a string.

isAsyncIterableLike

isAsyncIterableLike: <T = unknown>(value: unknown) => value is AsyncIterable<T>

isDefined

isDefined: <T>(obj: T) => obj is NonNullable<T>

Guard to filter out null or undefined values.

isDigit

isDigit: (value: unknown) => value is Digit

isHexDigit

isHexDigit: (value: unknown) => value is HexDigit

isInt

isInt: (obj: unknown) => obj is number

Check whether the given value is not just numeric, but is also an integer.

isIterableLike

isIterableLike: <T = unknown>(value: unknown) => value is Iterable<T>

isIteratorLike

isIteratorLike: <T = unknown>(value: unknown) => value is Iterator<T, unknown, unknown> | AsyncIterator<T, unknown, unknown>

isJSONArray

 function isJSONArray(value: unknown): value is JSONArray;

Type guard testing whether the value could be serialized as a JSON Array without losing information.

isJSONObject

 function isJSONObject(value: unknown): value is JSONObject;

Type guard for values which could be serialized as JSON Objects.

isJSONPrimitive

 function isJSONPrimitive(value: unknown): value is JSONPrimitive;

Type guard validating the value could be serialized as a JSON primitive.

isJSONSerializable

 function isJSONSerializable(value: unknown): value is JSONSerializable;

Type guard for any value which could be serialized natively as JSON.

isListOf

isListOf: <T>(list: unknown, predicate: (item: unknown, index: number, items: unknown[]) => item is T) => list is T[]

Guard to check if the given value is an array where all the items match the given predicate.

isObject

isObject: (obj: unknown) => obj is NonNullable<object>

Guard to check that the given value is defined and object-like.

isPlainObject

isPlainObject: (obj: unknown) => obj is Record<never, never>

Guard to check that the given value is defined, is an object, and seems to be a "plain" object, descending directly from Object. This won't prevent all shenanigans, but is a low-effort check.

isPromiseLike

isPromiseLike: <T = unknown>(value: unknown) => value is PromiseLike<T>

Type guard for a Promise-like "thenable".

isString

isString: (value: unknown) => value is string

Type guard for a string value. Just calls typeof, but could make complicated type guard compositions easier to read.

isUnaryPredicate

isUnaryPredicate: (obj: unknown) => obj is UnaryPredicate<unknown>

Tests whether the given object is a function and takes at least one parameter, and could maybe act as a unary predicate. Warning! Since no type information is available at runtime, it may not actually act as a predicate!

maybeInt

maybeInt: (text: string) => number | undefined

Convert to an integer, if it seems like it could be done safely. See decimal separator on Wikipedia for details on how this is probably very wrong in many countries.

scrubStackTrace

 function scrubStackTrace<E extends Error>(err: E, removeIf?: StackRemoveIf | undefined): E;

Wrap an Error in a proxy which cleans up the stack trace to be more human-readable. It filters out lines from third-party code, so you can quickly see your own code in the call stack. May optionally include some way of indicating additional lines which should be removed, so a guard function could make itself transparent, making it seem like the caller threw the error.

scrubStackTrace

 function scrubStackTrace(stack: string | undefined, removeIf?: StackRemoveIf | undefined): string | undefined;

validateJSONArray

 function validateJSONArray(value: unknown, seen?: Map<unknown, ValidationProblem[]>, path?: string[]): ValidationProblem[];

Try to validate the given value's items could be serialized as a JSON Array without losing information. An empty result array implies the value is a valid JSON Array.

validateJSONObject

 function validateJSONObject(value: unknown, seen?: Map<unknown, ValidationProblem[]>, path?: string[]): ValidationProblem[];

Try to validate the given value could be serialized as a JSON Object without losing information. An empty result array means the value is a valid JSON Object.

validateJSONPrimitive

 function validateJSONPrimitive(value: unknown, path?: string[]): ValidationProblem[];

Try to validate the given value could be serialized as a JSON literal primitive without losing information. An empty result array implies the value is a valid JSON primitive.

validateJSONSerializable

 function validateJSONSerializable(value: unknown, seen?: Map<unknown, ValidationProblem[]>, path?: string[]): ValidationProblem[];

Try to validate that the given value could be serialized correctly as JSON without losing information. An empty result array implies the value is valid JSON.

Interfaces

ThrowOnError

export interface ThrowOnError 

Mixin added to function call options to indicate whether it should throw, or silently swallow the error.

ValidationErrorOptions

export interface ValidationErrorOptions extends ErrorOptions 

ValidationProblem

export interface ValidationProblem 

A problem encountered while attempting to validate a value against a type guard/schema.

TypeAliases

Digit

type Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9";

HexDigit

type HexDigit = Digit | "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f";

MessageOrError

type MessageOrError = string | Error | (() => (string | Error));

A message, an error, or something which can generate one of those.

StackRemoveIf

type StackRemoveIf = Predicate<string> | RegExp | string;

Specifier for which lines of a stack trace should be removed.

Variables

NO_THROW

NO_THROW: Readonly<{
    readonly throwOnError: false;
}>

Value of ThrowOnError which will avoid throwing.

notPlainObject

notPlainObject: unique symbol

A symbol which can be exposed when you want isPlainObject to be false for an object. It doesn't matter what the value is.

Package Sidebar

Install

npm i @rickosborne/guard

Weekly Downloads

0

Version

2025.3.12

License

CC-BY-NC-SA-4.0

Unpacked Size

126 kB

Total Files

128

Last publish

Collaborators

  • rickosborne