@chaisser/type-guard
v1.0.0
Published
Runtime type guards and validators
Downloads
66
Maintainers
Readme
🛡️ @chaisser/type-guard
Runtime type guards and validators with full TypeScript support
✨ Features
- 🎯 Type-safe - Full TypeScript support with automatic type narrowing
- 🧪 30+ guards - Comprehensive coverage of all JavaScript types
- ✅ Assertions - Throw-on-failure assertions with
TypeGuardError - 🔍 Structural checks - Plain objects, promises, maps, sets, typed arrays
- 📏 Number precision - Finite, integer, safe integer, NaN detection
- 🧹 Emptiness checks - Works on strings, arrays, objects, maps, sets
- 🪶 Zero dependencies - Lightweight and tree-shakeable
- 🏎️ ESM + CJS - Dual module format support
📦 Installation
npm install @chaisser/type-guard
# or
yarn add @chaisser/type-guard
# or
pnpm add @chaisser/type-guard🚀 Quick Start
import {
// Primitive guards
isString,
isNumber,
isBoolean,
isNull,
isUndefined,
isNil,
// Structural guards
isPlainObject,
isArray,
isDate,
isPromise,
// Emptiness
isEmpty,
isBlank,
// Assertions
assertString,
assertArray,
assertNonNil,
} from '@chaisser/type-guard';
// Type guards narrow types automatically
function process(value: unknown) {
if (isString(value)) {
console.log(value.toUpperCase()); // TypeScript knows it's string
}
}
// Assertions throw TypeGuardError on mismatch
function greet(name: unknown) {
assertString(name);
return `Hello, ${name}`;
}
// Check emptiness for any container
isEmpty(null); // true
isEmpty(''); // true
isEmpty([]); // true
isEmpty({}); // true
isEmpty(new Map()); // true
isEmpty('hello'); // false📖 What It Does
This package provides runtime type checking utilities that integrate seamlessly with TypeScript's type system. Every guard function acts as a type predicate, so TypeScript automatically narrows types in conditional branches. Assertion functions provide a throw-based alternative for validating inputs at function boundaries.
🎯 How It Works
The package is organized into categories:
- Primitive Guards - Check for basic types (string, number, boolean, symbol, bigint, null, undefined)
- Number Guards - Precision checks (finite, integer, safe integer, NaN)
- Structural Guards - Object types (plain object, array, date, regex, error, promise, map, set, typed array)
- Emptiness Guards - Check if containers are empty (string, array, object, map, set)
- Assertions - Throw
TypeGuardErrorinstead of returning boolean
🎨 What It's Useful For
- API Input Validation - Validate incoming request data at runtime
- Type Narrowing - Help TypeScript understand unknown values in conditional branches
- Defensive Programming - Guard against unexpected data shapes
- Form Validation - Check user input types before processing
- Configuration Parsing - Validate parsed JSON/yaml config structures
- Library Authoring - Provide clear error messages for invalid arguments
- Data Sanitization - Filter and validate data from external sources
💡 Usage Examples
Primitive Checks
import { isString, isNumber, isBoolean, isNil, isPrimitive } from '@chaisser/type-guard';
isString('hello'); // true
isString(42); // false
isNumber(42); // true
isNumber(NaN); // false (NaN is excluded)
isNumber('42'); // false
isBoolean(true); // true
isBoolean(0); // false
isNil(null); // true
isNil(undefined); // true
isNil(0); // false
isPrimitive('hi'); // true
isPrimitive({}); // falseNumber Precision
import { isFiniteNumber, isInteger, isSafeInteger, isNaNValue } from '@chaisser/type-guard';
isFiniteNumber(42); // true
isFiniteNumber(Infinity); // false
isFiniteNumber(NaN); // false
isInteger(7); // true
isInteger(3.14); // false
isSafeInteger(42); // true
isSafeInteger(Number.MAX_SAFE_INTEGER + 1); // false
isNaNValue(NaN); // true
isNaNValue(42); // falseStructural Checks
import {
isPlainObject, isArray, isDate, isRegExp,
isError, isPromise, isMap, isSet, isTypedArray
} from '@chaisser/type-guard';
isPlainObject({}); // true
isPlainObject(Object.create(null)); // true
isPlainObject(new Date()); // false
isArray([1, 2, 3]); // true
isArray({ length: 3 }); // false
isDate(new Date()); // true
isDate(new Date('invalid')); // false (invalid date)
isPromise(Promise.resolve(42)); // true
isPromise({ then: () => {} }); // true (thenable)
isMap(new Map()); // true
isSet(new Set([1, 2])); // true
isTypedArray(new Uint8Array(4)); // trueEmptiness Checks
import { isEmpty, isBlank } from '@chaisser/type-guard';
// Works across all container types
isEmpty(null); // true
isEmpty(undefined); // true
isEmpty(''); // true
isEmpty([]); // true
isEmpty({}); // true
isEmpty(new Map()); // true
isEmpty(new Set()); // true
isEmpty('hello'); // false
isEmpty([1]); // false
isEmpty({ a: 1 }); // false
// String-specific blank check
isBlank(''); // true
isBlank(' '); // true
isBlank('\t\n'); // true
isBlank('hello'); // falseAssertions
import {
assertString, assertNumber, assertArray,
assertPlainObject, assertNonNil, assertDate,
TypeGuardError
} from '@chaisser/type-guard';
// Passes silently when correct
assertString('hello');
assertNumber(42);
assertArray([1, 2, 3]);
// Throws TypeGuardError when wrong
try {
assertString(42);
} catch (e) {
console.log(e instanceof TypeGuardError); // true
console.log(e.message); // "Expected string, got number"
}
// Great for function boundaries
function processUser(data: unknown) {
assertPlainObject(data);
assertNonNil(data.name);
// TypeScript now knows data is Record<string, unknown>
}📚 API Reference
Primitive Guards
| Function | Type Predicate | Description |
|---|---|---|
| isString(value) | value is string | Checks if value is a string |
| isNumber(value) | value is number | Checks if value is a number (excludes NaN) |
| isBoolean(value) | value is boolean | Checks if value is a boolean |
| isSymbol(value) | value is symbol | Checks if value is a symbol |
| isBigInt(value) | value is bigint | Checks if value is a bigint |
| isNull(value) | value is null | Checks if value is null |
| isUndefined(value) | value is undefined | Checks if value is undefined |
| isNil(value) | value is null \| undefined | Checks if value is null or undefined |
| isPrimitive(value) | value is primitive | Checks if value is a primitive type |
Number Guards
| Function | Type Predicate | Description |
|---|---|---|
| isFiniteNumber(value) | value is number | Finite number (excludes NaN, Infinity) |
| isInteger(value) | value is number | Integer number |
| isSafeInteger(value) | value is number | Safe integer (within MAX_SAFE_INTEGER) |
| isNaNValue(value) | boolean | Checks if value is NaN |
Structural Guards
| Function | Type Predicate | Description |
|---|---|---|
| isObject(value) | value is object | Any non-null object |
| isPlainObject(value) | value is Record<string, unknown> | Plain object ({} or Object.create(null)) |
| isFunction(value) | value is Function | Any function or class |
| isArray(value) | value is unknown[] | An array |
| isDate(value) | value is Date | Valid Date instance |
| isRegExp(value) | value is RegExp | RegExp instance |
| isError(value) | value is Error | Error instance |
| isPromise(value) | value is Promise<T> | Promise or thenable object |
| isMap(value) | value is Map<K, V> | Map instance |
| isSet(value) | value is Set<T> | Set instance |
| isTypedArray(value) | boolean | Any typed array |
Emptiness Guards
| Function | Returns | Description |
|---|---|---|
| isEmpty(value) | boolean | Empty container (null, "", [], {}, empty Map/Set) |
| isBlank(value) | boolean | Empty or whitespace-only string |
Assertions
Each assertion throws TypeGuardError if the check fails.
| Function | Asserts |
|---|---|
| assertString(value) | Value is a string |
| assertNumber(value) | Value is a number (not NaN) |
| assertBoolean(value) | Value is a boolean |
| assertFunction(value) | Value is a function |
| assertArray(value) | Value is an Array |
| assertPlainObject(value) | Value is a plain Object |
| assertNonNil(value) | Value is neither null nor undefined |
| assertDate(value) | Value is a valid Date |
🔗 Related Packages
Explore our other utility packages in the @chaisser namespace:
- @chaisser/type-guard (this package) - Runtime type guards and validators
- @chaisser/string-wizard - Advanced string manipulation
- @chaisser/human-time - Human-readable time formatting
- @chaisser/obj-path - Object path traversal
- @chaisser/regex-humanizer - Regex pattern explanation
- @chaisser/debounce-throttle - Rate limiting utilities
- @chaisser/color-utils - Color conversion utilities
- @chaisser/deep-clone - Deep cloning functions
- @chaisser/array-group-by - Array grouping utilities
- @chaisser/uuid-v7 - UUID v7 generator
- @chaisser/password-strength - Password strength checker
- @chaisser/wait-for - Promise-based wait utilities
- @chaisser/merge-objects - Object merge utilities
- @chaisser/chunk-array - Array chunking functions
- @chaisser/event-emitter - Typed event emitter
🔒 License
MIT - Free to use in personal and commercial projects
👨 Developed by
Doruk Karaboncuk [email protected]
📄 Repository
- GitHub: @chaisser
- NPM: @chaisser/type-guard
🤝 Contributing
Contributions are welcome! Feel free to:
- Report bugs
- Suggest new features
- Submit pull requests
- Improve documentation
📞 Support
For issues, questions, or suggestions, please reach out through:
- Email: [email protected]
- GitHub Issues: Create an issue
Made with ❤️ by @chaisser
