npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

utility-guards

v3.0.0-rc1

Published

Utils for runtime and static type checking in JS and TS

Downloads

38

Readme

Features:

  • 🛠️ Reliable type checking for JS runtime
  • 📦 Zero dependencies and only 1kb gzipped size
  • 📦 Tree-shaking friendly
  • 🔩 Full Typescript guard support
  • 🔩 Isomorphic: works in browser and node.js
  • 🔑 Addon: validate and validateStrict validators for runtime values (object) validation

API Reference


npm install utility-guards

Usage

// using named imports (tree-shaking friendly)
import { isString, isNumber, isNil, $not } from 'utility-guards';

isString('42'); // true
isNumber(42); // false

isString('42'); // true
isNumber(42); // false
$not(isNil)(0); // true
// using standalone imports (tree-shaking friendly)
import isString from 'utility-guards/isString';
import isNumber from 'utility-guards/isNumber';
import isNil from 'utility-guards/isNil';
import $not from 'utility-guards/not';

isString('42'); // true
isNumber(42); // false
$not(isNil)(0); // true
// Using default import – `is` namespace object
import is from 'utility-guards';

is.String('42'); // true
is.Number(42); // false
is.$not(is.Nil)(0); // true

API

isString(value)

Check if value is an string literal or string created by String constructor

isString('abc'); // true
isString(new String('abc')); // true
isString(42); // false

isNumber(value)

Check if value is an number literal or number created by Number constructor and not NaN

ℹ️ Although NaN is considered a number in JS, it's not a valid number in most cases you want to check if value is a valid number, so isNumber(NaN) returns false

isNumber(42); // true
isNumber(new Number(42)); // true
isNumber('42'); // false
isNumber(NaN); // false

isBigInt(value)

Check if value is an BigInt literal or BigInt created by BigInt constructor

isBigInt(42n); // true
isBigInt(BigInt(42)); // true
isBigInt(42); // false

isBoolean(value)

Check if value is an boolean

isBoolean(true); // true
isBoolean(false); // true
isBoolean(42); // false

isNaN(value)

Check if value is an NaN value.

ℹ️ This method is based on Number.isNaN and is not the same as global isNaN which converts value to number before checking

isNaN(NaN); // true
isNaN(2 + {}); // true
isNaN(42); // false
isNaN({}); // false

isUndefined(value)

Check if value is a undefined

isUndefined(undefined); // true
isUndefined(null); // false

isNull(value)

Check if value is a null

isNull(null); // true
isNull(undefined); // false

isNil(value)

Check if value is a null or undefined

isNil(null); // true
isNil(undefined); // true
isNil(0); // false

isPrimitive(value)

Check if value is a primitive

ℹ️ Primitive values in JS are: string, number, boolean, null, undefined, symbol, bigint

isPrimitive(42); // true
isPrimitive([1, 2, 3]); // false

isSymbol(value)

Check if value is a Symbol

isSymbol(Symbol('42')); // true
isSymbol('42'); // false

isRegExp(value)

Check if value is a RegExp object or RegExp literal

isRegExp(/\w+/); // true
isRegExp(new RegExp('\\w+')); // true

isError(value)

Check if value is an JS Error object

isError(new Error()); // true
isError(new TypeError()); // true

isAnyObject(value)

Check if value is a language type object (except null)

ℹ️ This method is not type safe and may lead to unexpected runtime errors. You probably want to use isPlainObject instead

isAnyObject({}); // true
isAnyObject([]); // true
isAnyObject(new Map()); // true
isAnyObject(new String()); // true

isPlainObject(value)

Check if value is a plain JavaScript object (excluding special classes or objects with other prototypes). It may be object literal {}, instance created by Object constructor or using Object.create(null | Object)

isPlainObject({}); // true
isPlainObject([]); // false
isPlainObject(new Map()); // false
isPlainObject(new String()); // false

isArray(value)

Check if value is array

isArray([]); // true
isArray({ 0: 'a', length: 10 }); // false

isFunction(value)

Check if value is an any function (except class definition)

isFunction(() => {}); // true
isFunction(function () {}); // true
isFunction(class {}); // false

isClass(value)

Check if value is a class definition

isClass(class {}); // true
isClass(() => {}); // false
isClass(function () {}); // false

isPromise(value)

Check if value is a native promise object

isPromise(Promise.resolve()); // true
isPromise(new Promise(() => {})); // true
isPromise({ then: () => {} }); // false

isPromiseLike(value)

Check if value is a promise-like object (has then method)

isPromiseLike(Promise.resolve()); // true
isPromiseLike(new Promise(() => {})); // true
isPromiseLike({ then: () => {} }); // true

isIterable(value)

Check if value is iterable (arrays, strings, maps, sets, etc.)

isIterable([]); // true
isIterable('42'); // true
isIterable(new Map()); // true

isDate(value)

Check if value is a valid JS Date object

isDate(new Date()); // true
isDate(new Date('Invalid Date')); // false

isHas(value, propertyName)

(value, propertyName) => boolean
(propertyName) => (value) => boolean

Check if value is an any object and has a direct property with given name

ℹ️ This method based on Object.prototype.hasOwnProperty and does not check prototype chain

isHas({ a: 42 }, 'a'); // true
isHas({ a: 42 }, 'b'); // false

isHasIn(value, propertyName)

(value, propertyName) => boolean
(propertyName) => (value) => boolean

Check if value is an any object and has a direct or inherited property with given name

ℹ️ This method based on in operator and checks prototype chain

isHasIn({ a: 42 }, 'a'); // true
isHasIn({ a: 42 }, 'b'); // false
isHasIn({ a: 42 }, 'toString'); // true

class A {
    method() {}
}

isHasIn(new A(), 'method'); // true

isArrayOf(value, guard)

(value, guard) => boolean
(guard) => (value) => boolean

Check if value is an array and all elements of the array match a given guard

isArrayOf([1, 2, 3], isNumber); // true
isArrayOf([1, 2, 3], isString); // false

isInstanceOf(value, constructor)

(value, constructor) => boolean
(constructor) => (value) => boolean

Check if value is instance of given constructor

ℹ️ This method based on instanceof operator

isInstanceOf(new Map(), Map); // true
isInstanceOf(new Map(), Set); // false

isEmpty(value)

Check if value is empty.

Value is considered as empty if it's:

  • Empty object: {}
  • Empty array: []
  • Empty Map: new Map()
  • Empty Set: new Set()
  • Empty string: ''
  • Nullable value: null or undefined
isEmpty({}); // true
isEmpty(new Set()); // true
isEmpty(null); // true
isEmpty(''); // true
isEmpty(0); // false

isFalsy(value)

Check if value is falsy

isFalsy(0); // true
isFalsy(''); // true
isFalsy(false); // true
isFalsy(null); // true
isFalsy(undefined); // true
isFalsy(NaN); // true
isFalsy(42); // false

isAny(value)

Returns true for any value. This is special case guard that originally was created to be used with validate function.

import validate from 'utility-guards/validate';

const schema = {
    a: isAny,
    b: isAny,
    c: isAny,
};

validate({ a: 42, b: '42', c: true }, schema); // true

is(value, expectedValue)

💡 You can use is container as a guard function

(value, expectedValue) => boolean
(value, expectedValue, isEqual) => boolean

(expectedValue) => (value) => boolean
(expectedValue, isEqual) => (value) => boolean

Check if value is equal to a given expected value.

ℹ️ By default will use Object.is for comparison, but you can pass custom isEqual function as a third argument

is(42, 42); // true

const isExactly42 = is(42);

isExactly42(42); // true
isExactly42('anything else'); // false
import is from 'utility-guards';
import isEqual from 'lodash/isEqual';

const isMyObject = is({ a: 3 }, isEqual);

isMyObject({ a: 3 }); // true
isMyObject({ a: 3, b: 4 }); // false

utility methods

All methods that starts with $ are utility methods for manipulating with guards

$not(guard)

Inverse given guard

const notIsNil = $not(isNil);

const arr = [1, null, 2, undefined, 3];
const filtered = arr.filter(notIsNil);

console.log(filtered); // [1, 2, 3] (type: number[])

$some(guard1, guard2, ...)

Combine multiple guards with some logic (logical OR)

const isNumberOrString = $some(isNumber, isString);

isNumberOrString(42); // true
isNumberOrString('42'); // true
isNumberOrString(true); // false

$every(guard1, guard2, ...)

Combine multiple guards with every logic (logical AND)

const isEmptyArray = $every(isArray, isEmpty);

isEmptyArray([]); // true
isEmptyArray([1, 2, 3]); // false

validate addon

(value, schema, options) => boolean
(schema, options) => (value) => boolean

Allows to validate runtime values (objects, arrays) with given schema or guard

Usage

Validate object with schema

import validate from 'utility-guards/validate';
import { isString, isNil, isBoolean } from 'utility-guards';

const obj = JSON.parse('...');

const schema = {
    a: isNumber,
    b: $some(isString, isNil), // string or nil
    c: {
        d: isBoolean,
        e: {
            f: isNumber,
            g: isString,
        },
    },
};

if (validate(obj, schema)) {
    // type of obj is inferred
    // { a: number, b: string | null, c: { d: boolean, e: { f: number, g: string } } }
    obj.c.e.f; // OK
} else {
    obj.c.e.f; // TS Error
}

Validate array with schema

import validate from 'utility-guards/validate';
import { isString, isNil, isBoolean, isArrayOf } from 'utility-guards';

const arr = JSON.parse('...');

const schema = [
    isString,
    isNil, // string or nil
    {
        d: isBoolean,
        e: isArrayOf(isNumber), // array of numbers only
    },
];

if (validate(arr, schema)) {
    // type of arr is inferred
    // [string, string | null, { d: boolean, e: number[] }]
    arr[2].e[0]; // OK
} else {
    arr[2].e[0]; // TS Error
}

Validate function args

One of the useful use-cases is to validate overloaded function arguments

import validate from 'utility-guards/validate';

type FunctionExample = {
    (value: string): void;
    (value: string, otherValue: number): void;
    (value: string, otherValue: number[]): void;
};

const example: FunctionExample = (...args: unknown[]) => {
    if (validate(args, [isString])) {
        const [value] = args; // [string]
    }
    if (validate(args, [isString, isNumber])) {
        const [value, otherValue] = args; // [string, number]
    }
    if (validate(args, [isString, isArrayOf(isNumber)])) {
        const [value, otherValue] = args; // [string, number[]]
    }

    // fallback
};

Validate value with guard

import validate from 'utility-guards/validate';
import { isArray, isEmpty, isString, isNil, isBoolean, $every, $some } from 'utility-guards';

const value = JSON.parse('...');

validate(value, isNumber); // is number
validate(value, $some(isNumber, isString)); // is number | string
validate(value, $every(isArray, isEmpty)); // is []

validate([1, 2, 3], isArrayOf(isNumber)); // true
validate([1, 2, 3, 'asd'], isArrayOf(isNumber)); // false

Allow extra properties

(value, schema) => boolean
(schema) => (value) => boolean

For objects and arrays, by default, validate method checks if value has all properties defined in schema. If you want to allow extra properties, you can pass allowExtra: true

import validate from 'utility-guards/validate';
import { isString, isNumber } from 'utility-guards';

const schema = {
    a: isNumber,
    b: isString,
};

// object
validate({ a: 42, b: '42', c: true }, schema); // false
validate({ a: 42, b: '42', c: true }, schema, { allowExtra: true }); // true

// array
validate([42, '42', true], [isNumber, isString]); // false
validate([42, '42', true], [isNumber, isString], { allowExtra: true }); // true

Compose and create custom guard

const isOkCode = $some(is(200), is(201), is(202));

const isUserProfile = validate({
    id: isNumber,
    name: isString,
    age: $some(isNumber, isNil),
    avatarUrl: $some(isString, isNil),
});

const isSuccessResult = validate({
    ok: is(true),
    code: isOkCode,
    result: {
        id: is.Number,
        users: is.ArrayOf(isUserProfile),
    },
});

// true
isSuccessResult({
    ok: true,
    code: 200,
    result: [
        {
            id: 42,
            user: {
                id: 42,
                name: 'John',
                age: null,
                avatarUrl: null,
            },
        },
    ],
});