A comprehensive collection of performant type guards and assertions with excellent TypeScript support
npm install @tool-belt/type-predicates

A comprehensive collection of performant type guards and assertions with excellent TypeScript support. This library serves as a drop-in replacement for Node.js's util/types module, while offering significantly better type inference, more extensive functionality, and cross-platform compatibility.
If you find @tool-belt/type-predicates helpful, please consider sponsoring the development:
Your support helps maintain and improve this library for the community! 🚀
- 🚀 Better TypeScript Support: Advanced type inference with generics and precise type narrowing
- 📦 Zero Dependencies: Lightweight and self-contained
- 🌳 Tree-Shakeable: Full ESM support for optimal bundle sizes
- 🌐 Cross-Platform: Works in browsers, Node.js, and any JavaScript environment
- ✅ Thorough Testing: Comprehensive test coverage for both runtime behavior and type safety
- 🔧 Extensive API: More comprehensive than Node.js built-in utilities
- 🎯 Type Guards & Assertions: Every type check is available in both guard and assertion forms
``bash`
npm install @tool-belt/type-predicates
`bash`
pnpm add @tool-belt/type-predicates
`bash`
yarn add @tool-belt/type-predicates
This library works in all modern browsers and Node.js environments. It's compiled to ES modules and CommonJS, with full support for tree-shaking to minimize bundle size.
`typescript
// node:util/types
import { isArray } from 'util/types';
const arr: unknown = ['a', 'b', 'c'];
if (isArray(arr)) {
// arr is typed as "unknown[]" - not very useful
}
// @tool-belt/type-predicates
import { isArray } from '@tool-belt/type-predicates';
const arr: unknown = ['a', 'b', 'c'];
if (isArray
// arr is typed as "string[]" - much better!
}
`
`typescript
import { assertIsString, assertIsArray } from '@tool-belt/type-predicates';
// Throws TypeError if not a string
assertIsString(value);
// After this line, TypeScript knows 'value' is a string
// With custom error messages
assertIsArray(data, { message: 'Configuration must be an array' });
// With nested validation
assertIsArray
valueValidator: (item) => typeof item === 'number',
message: 'Expected array of numbers',
});
`
`typescript
import {
isUnion,
isString,
isNumber,
createTypeGuard,
} from '@tool-belt/type-predicates';
// Combine multiple type guards
const isStringOrNumber = isUnion(isString, isNumber);
// Create custom type guards
const isPositiveNumber = createTypeGuard
(value) => isNumber(value) && value > 0,
);
`
Every guard returns a type predicate for TypeScript type narrowing:
`typescript
import {
isArray,
isObject,
isString,
isNumber,
isBoolean,
isFunction,
isPromise,
isMap,
isSet,
isDate,
isRegExp,
isError,
isNull,
isUndefined,
isNullish,
isDefined,
// ... and many more
} from '@tool-belt/type-predicates';
// Use in conditionals
if (isString(value)) {
// TypeScript knows 'value' is a string here
console.log(value.toUpperCase());
}
// Use with array methods
const strings = mixedArray.filter(isString);
// strings is typed as string[]
`
Every guard has a corresponding assertion that throws on failure:
`typescript
import {
assertIsArray,
assertIsObject,
assertIsString,
// ... all guards have assertion versions
} from '@tool-belt/type-predicates';
function processConfig(config: unknown) {
assertIsObject(config);
// TypeScript now knows config is an object
assertIsString(config.name, { message: 'Config name must be a string' });
// config.name is now typed as string
}
`
#### Deep Validation
`typescript
import { isArray, isObject, isString } from '@tool-belt/type-predicates';
// Validate array elements
const isStringArray = (value: unknown): value is string[] =>
isArray(value, { valueValidator: isString });
// Validate object values
const isStringRecord = (value: unknown): value is Record
isObject(value, { valueValidator: isString });
`
#### Utility Functions
`typescript
import { createTypeGuard, isUnion } from '@tool-belt/type-predicates';
// Create custom guards
const isNonEmptyString = createTypeGuard
(value) => isString(value) && value.length > 0,
);
// Union types
const isNumberOrString = isUnion(isNumber, isString);
`
- isString / assertIsStringisNumber
- / assertIsNumberisBoolean
- / assertIsBooleanisBigInt
- / assertIsBigIntisSymbol
- / assertIsSymbolisUndefined
- / assertIsUndefinedisNull
- / assertIsNullisNullish
- / assertIsNullishisDefined
- / assertIsDefinedisNotNull
- / assertIsNotNullisNotNullish
- / assertIsNotNullish
- isObject / assertIsObject - Checks if value is an object (not null)isPlainObject
- / assertIsPlainObject - Checks if value is a plain object (not a class instance)isRecord
- / assertIsRecord - Validates an object with specific key and value typesisEmptyObject
- / assertIsEmptyObject - Checks if object has no own propertiesisBoxedPrimitive
- / assertIsBoxedPrimitive - Checks if value is a boxed primitive
- isArray / assertIsArray - Validates arrays with optional element type checkingisEmptyArray
- / assertIsEmptyArray - Checks if array has length of 0isNonEmptyArray
- / assertIsNonEmptyArray - Checks if array has length > 0isMap
- / assertIsMap - Validates Map objects with optional key/value type checkingisSet
- / assertIsSet - Validates Set objects with optional value type checkingisWeakMap
- / assertIsWeakMap - Checks if value is a WeakMapisWeakSet
- / assertIsWeakSet - Checks if value is a WeakSet
- isFunction / assertIsFunction - Checks if value is a functionisAsyncFunction
- / assertIsAsyncFunction - Checks if value is an async functionisGeneratorFunction
- / assertIsGeneratorFunction - Checks if value is a generator functionisAsyncGeneratorFunction
- / assertIsAsyncGeneratorFunction - Checks if value is an async generator function
- isIterable / assertIsIterable - Validates iterable objectsisIterator
- / assertIsIterator - Validates iterator objectsisGenerator
- / assertIsGenerator - Checks if value is a generatorisAsyncGenerator
- / assertIsAsyncGenerator - Checks if value is an async generatorisAsyncIterable
- / assertIsAsyncIterable - Validates async iterable objectsisMapIterator
- / assertIsMapIterator - Checks if value is a Map iteratorisSetIterator
- / assertIsSetIterator - Checks if value is a Set iterator
- isError / assertIsError - Checks if value is an ErrorisNativeError
- / assertIsNativeError - Checks if value is a native Error type
- isNaN / assertIsNaN - Checks if value is NaNisFinite
- / assertIsFinite - Checks if value is a finite numberisInteger
- / assertIsInteger - Checks if value is an integerisSafeInteger
- / assertIsSafeInteger - Checks if value is a safe integer
- isEmptyString / assertIsEmptyString - Checks if string has length of 0isNonEmptyString
- / assertIsNonEmptyString - Checks if string has length > 0
- isBuffer / assertIsBuffer - Checks if value is a BufferisArrayBuffer
- / assertIsArrayBuffer - Checks if value is an ArrayBufferisSharedArrayBuffer
- / assertIsSharedArrayBuffer - Checks if value is a SharedArrayBufferisAnyArrayBuffer
- / assertIsAnyArrayBuffer - Checks if value is any kind of ArrayBufferisArrayBufferView
- / assertIsArrayBufferView - Checks if value is an ArrayBufferViewisDataView
- / assertIsDataView - Checks if value is a DataViewisTypedArray
- / assertIsTypedArray - Checks if value is any TypedArray
- Various specific TypedArray checkers (Int8Array, Uint8Array, etc.)
- isDate / assertIsDate - Checks if value is a DateisRegExp
- / assertIsRegExp - Checks if value is a RegExpisPromise
- / assertIsPromise - Checks if value is a PromiseisArgumentsObject
- / assertIsArgumentsObject - Checks if value is an arguments object
You can create your own type guards using the createTypeGuard utility:
`typescript
import { createTypeGuard, isNumber } from '@tool-belt/type-predicates';
// Create a type guard for positive numbers
const isPositiveNumber = createTypeGuard
(value) => isNumber(value) && value > 0,
);
// Use it like any other guard
if (isPositiveNumber(value)) {
// TypeScript knows value is a number here
// Runtime has verified value > 0
}
`
`typescript
import { isError } from '@tool-belt/type-predicates';
try {
// Your code that might throw
} catch (error) {
// TypeScript types catch blocks as 'unknown'
if (isError(error)) {
console.error(error.message);
console.error(error.stack);
}
}
``
MIT