包详细信息

utility-guards

resetand31MIT3.0.1

Utils for runtime and static type checking in JS and TS

guard, typescript, types, is

自述文件

utility-guards

Set of guard function for runtime type checking in JavaScript with complete TypeScript support

npm package codecov package gzipped size



Motivation

JavaScript has a notoriously inconsistent system for runtime type checking — with scattered use of typeof, instanceof, Array.isArray, Object.prototype.hasOwnProperty, and more. As well, TypeScript does not work properly with all of these checks, leading to confusion and bugs.

This library was created to unify all these scattered patterns into a consistent, type-safe, and minimal API.

Features

  • 🧪 Simple runtime type checking
  • 💡 Full TypeScript type inference support
  • 📦 Tree-shaking friendly and zero dependencies

Installation

npm install utility-guards

Usage

import from the main package

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

isString(...);
isNumber(...);
isNil(...);

import from the sub-packages

import isString from 'utility-guards/isString';
import isNumber from 'utility-guards/isNumber';
import isNil from 'utility-guards/isNil';

isString(...);
isNumber(...);
isNil(...);

use is default export container

import is from 'utility-guards';

is.String(...)
is.Number(...)
is.Nil(...)

Table of Contents

API

Primitive Checks

Object Checks

Function & Class Checks

Special Structures

Advanced Structural Guards

Combinators

Utility


API

Primitive Checks

isString

Checks if a value is a string (based on typeof)

isString('hello'); // true
isString(123); // false

isNumber

Checks if a value is a number (based on typeof)

isNumber(123); // true
isNumber('123'); // false

isFiniteNumber

Checks if a values is a finite number (not NaN, Infinity, or -Infinity)

isFiniteNumber(123); // true
isFiniteNumber(NaN); // false
isFiniteNumber(Infinity); // false
isFiniteNumber('42'); // false

isBoolean

Checks if a value is a boolean (based on typeof)

isBoolean(true); // true
isBoolean(0); // false

isBigInt

Checks if value is a bigint (based on typeof)

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

isSymbol

Checks for symbol type (based on typeof)

isSymbol(Symbol('foo')); // true

isNull

Checks if value is exactly null.

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

isUndefined

Checks if value is exactly undefined.

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

isNil

Checks if value is null or undefined.

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

isNaN

Strict NaN check

isNaN(NaN); // true
isNaN('foo'); // false

isPrimitive

Checks for JS primitive types including (string, number, boolean, bigint, symbol, null, and undefined).

isPrimitive('hello'); // true

isFalsy

Checks if value is falsy: false, 0, '', null, undefined

isFalsy(false); // true
isFalsy(0); // true
isFalsy(''); // true

Object Checks

isAnyObject

Loose check for object-like values (including arrays, maps).

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

isPlainObject

Strictly checks for plain objects with default prototype.

isPlainObject({}); // true
isPlainObject(new Map()); // false
isPlainObject(new MyClass()); // false
isPlainObject(Object.create(null)); // true

isEmpty

Checks if the value is empty (e.g. empty array, string, object, map, set).

isEmpty({}); // true
isEmpty([]); // true
isEmpty(''); // true
isEmpty(new Map()); // true
isEmpty(new Set()); // true

isArray

Checks if value is an array (based on Array.isArray)

isArray([]); // true
isArray({}); // false

isArrayOf

Checks if every item in an array passes a specified guard.

isArrayOf(['hello', 'world'], isString); // true
isArrayOf(['hello', 123], isString); // false

// can also use currying
is.ArrayOf(isString)(['hello', 'world']); // true

isTupleOf

Checks if the value is an array that exactly matches a given tuple schema.

isTupleOf(['hello', 123], [isString, isNumber]); // true
isTupleOf(['hello', 'world'], [isString, isNumber]); // false
isTupleOf([123], [isString, isNumber]); // false

isObjectOf

Checks if the value is an object that matches a given schema.

isObjectOf({ a: 1, b: 'hello' }, { a: isNumber, b: isString }); // true
isObjectOf({ a: 1, b: 'hello' }, { a: isNumber, b: isString, c: isBoolean }); // false

isObjectOf({ a: 1, b: 'hello', extra: true }, { a: isNumber, b: isString }); // true (see `isObjectExactOf` for strict check)

isObjectExactOf

Same as isObjectOf, but strictly checks that the object matches the schema without extra keys.

isObjectExactOf({ a: 1, b: 'hello', extra: true }, { a: isNumber, b: isString }); // false

Function & Class Checks

isFunction

Checks if a value is a function (but not a ES6 class constructor).

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

Although technically es6 classes are functions as well, it's can not be called like a regular function and in most majority of cases this is not the expected behavior. So this guard is designed to check for regular functions only

isClass

Checks if value is a ES6 class constructor. Uses Object.prototype.toString hack. Only works with ES6 classes defined with class keyword.

isClass(class MyClass {}); // true
isClass(function () {}); // false

Special Structures

isRegExp

Checks if value is a RegExp instance.

isRegExp(/abc/); // true
isRegExp(new RegExp('abc')); // true

isDate

Checks if value is a Date instance.

isDate(new Date()); // true
isDate(new Date('INVALID')); // true, includes invalid dates (see `isValidDate` for strict check)
isDate('2023-01-01'); // false

isValidDate

Same as isDate, but checks if the date is valid (i.e. not Invalid Date).

isValidDate(new Date()); // true
isValidDate(new Date('INVALID')); // false

isIterable

Checks if value is iterable, meaning it has a [Symbol.iterator] method and can be used in a for...of loop and spread operator.

isIterable(new Set([1, 2])); // true
isIterable(new Map()); // true
isIterable(new Map().keys()); // true
isIterable((function* () {})()); // true
isIterable({}); // false

isPromise

Checks if value is a native Promise instance.

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

isPromiseLike

Checks if value is a promise-like object, meaning it has a then method.

isPromiseLike(new Promise(() => {})); // true
isPromiseLike({ then: () => {} }); // true
isPromiseLike({ then: 'foo' }); // false

isError

Checks if value is an instance of Error.

isError(new Error('foo')); // true
isError(new TypeError('foo')); // true
isError(new MyCustomError('foo')); // true

Advanced Structural Guards

isHasOwn

Checks if object has an own property (not inherited).

class Cls {
    get key() {
        return 'value';
    }
}
const obj = { key: 'value' };

isHasOwn(obj, 'key'); // true
isHasOwn(new Cls(), 'key'); // false
isHasOwn('key')(obj); // support currying

isHasIn

Checks if property exists in object or its prototype chain.

isHasIn(obj, 'key'); // true
isHasIn(new Cls(), 'key'); // true
isHasIn('key')(obj); // support currying

isInstanceOf

Checks if value is instance of constructor using instanceof.

class A {}
class B extends A {}

isInstanceOf(new A(), A); // true
isInstanceOf(new B(), A); // true

isInstanceExactOf

Strict check that prototype is exactly the one from constructor (not a subclass).

isInstanceExactOf(new A(), A); // true
isInstanceExactOf(new B(), A); // false

Combinators

$not

Inverts a given guard

const isNotString = $not(isString);
isNotString(123); // true

$some

Logical OR combinator: passes if any guard returns true.

const isStringOrNumber = $some(isString, isNumber);
isStringOrNumber('hello'); // true
isStringOrNumber(123); // true

$every

Logical AND combinator: passes if all guards return true.

const isStringAndNotEmpty = $every(isString, $not(isEmpty));
isStringAndNotEmpty('hello'); // true
isStringAndNotEmpty(''); // false

Utility

is

Checks two values for equality using Object.is (or custom equality function). Can be used for build more complex guards (e.g. isObjectOf, isTupleOf etc.).

is(123, 123); // true
is(123)(123); // support currying

isAny

A guard that always returns true. Useful as a wildcard in validations.

isAny(ANYTHING); // true

Types

All guards follow this signature:

// basic guards with single argument
(value: unknown) => value is T

// guards with multiple arguments (isArrayOf, isTupleOf, isObjectOf, isInstanceOf, isHasOwn etc.)
// supports currying
(value: unknown, ...args: unknown[]) => value is T
(...args: unknown[]) => (value: unknown) => value is T

License

MIT © Resetand