utility-guards
v3.0.1
Published
Utils for runtime and static type checking in JS and TS
Maintainers
Readme
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-guardsUsage
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
isStringisNumberisFiniteNumberisBooleanisBigIntisSymbolisNullisUndefinedisNilisNaNisPrimitiveisFalsy
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); // falseisNumber
Checks if a value is a number (based on typeof)
isNumber(123); // true
isNumber('123'); // falseisFiniteNumber
Checks if a values is a finite number (not NaN, Infinity, or -Infinity)
isFiniteNumber(123); // true
isFiniteNumber(NaN); // false
isFiniteNumber(Infinity); // false
isFiniteNumber('42'); // falseisBoolean
Checks if a value is a boolean (based on typeof)
isBoolean(true); // true
isBoolean(0); // falseisBigInt
Checks if value is a bigint (based on typeof)
isBigInt(123n); // true
isBigInt(BigInt(123)); // true
isBigInt(123); // falseisSymbol
Checks for symbol type (based on typeof)
isSymbol(Symbol('foo')); // trueisNull
Checks if value is exactly null.
isNull(null); // true
isNull(undefined); // falseisUndefined
Checks if value is exactly undefined.
isUndefined(undefined); // true
isUndefined(null); // falseisNil
Checks if value is null or undefined.
isNil(null); // true
isNil(undefined); // trueisNaN
Strict NaN check
isNaN(NaN); // true
isNaN('foo'); // falseisPrimitive
Checks for JS primitive types including (string, number, boolean, bigint, symbol, null, and undefined).
isPrimitive('hello'); // trueisFalsy
Checks if value is falsy: false, 0, '', null, undefined
isFalsy(false); // true
isFalsy(0); // true
isFalsy(''); // trueObject Checks
isAnyObject
Loose check for object-like values (including arrays, maps).
isAnyObject({}); // true
isAnyObject([]); // true
isAnyObject(new Map()); // true
isAnyObject(new MyClass()); // trueisPlainObject
Strictly checks for plain objects with default prototype.
isPlainObject({}); // true
isPlainObject(new Map()); // false
isPlainObject(new MyClass()); // false
isPlainObject(Object.create(null)); // trueisEmpty
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()); // trueisArray
Checks if value is an array (based on Array.isArray)
isArray([]); // true
isArray({}); // falseisArrayOf
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']); // trueisTupleOf
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]); // falseisObjectOf
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 }); // falseFunction & Class Checks
isFunction
Checks if a value is a function (but not a ES6 class constructor).
isFunction(() => {}); // true
isFunction(function () {}); // true
isFunction(class MyClass {}); // falseAlthough 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 () {}); // falseSpecial Structures
isRegExp
Checks if value is a RegExp instance.
isRegExp(/abc/); // true
isRegExp(new RegExp('abc')); // trueisDate
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'); // falseisValidDate
Same as isDate, but checks if the date is valid (i.e. not Invalid Date).
isValidDate(new Date()); // true
isValidDate(new Date('INVALID')); // falseisIterable
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({}); // falseisPromise
Checks if value is a native Promise instance.
isPromise(new Promise(() => {})); // true
isPromise({ then: () => {} }); // falseisPromiseLike
Checks if value is a promise-like object, meaning it has a then method.
isPromiseLike(new Promise(() => {})); // true
isPromiseLike({ then: () => {} }); // true
isPromiseLike({ then: 'foo' }); // falseisError
Checks if value is an instance of Error.
isError(new Error('foo')); // true
isError(new TypeError('foo')); // true
isError(new MyCustomError('foo')); // trueAdvanced 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 curryingisHasIn
Checks if property exists in object or its prototype chain.
isHasIn(obj, 'key'); // true
isHasIn(new Cls(), 'key'); // true
isHasIn('key')(obj); // support curryingisInstanceOf
Checks if value is instance of constructor using instanceof.
class A {}
class B extends A {}
isInstanceOf(new A(), A); // true
isInstanceOf(new B(), A); // trueisInstanceExactOf
Strict check that prototype is exactly the one from constructor (not a subclass).
isInstanceExactOf(new A(), A); // true
isInstanceExactOf(new B(), A); // falseCombinators
$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(''); // falseUtility
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 curryingisAny
A guard that always returns true. Useful as a wildcard in validations.
isAny(ANYTHING); // trueTypes
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 TLicense
MIT © Resetand
