A state-of-the-art, high-performance JavaScript utility library with a small bundle size and strong type annotations.
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Comprehensive type checking functions providing TypeScript type guards for runtime type validation. Essential for type-safe JavaScript development and runtime type checking.
Functions for checking null and undefined values with strong TypeScript integration.
/**
* Checks if value is not null or undefined (primary type guard)
* @param x - Value to check
* @returns Type guard boolean indicating value is not null/undefined
*/
function isNotNil<T>(x: T | null | undefined): x is T;
/**
* Checks if value is null or undefined
* @param value - Value to check
* @returns Type guard boolean indicating value is null or undefined
*/
function isNil(value: unknown): value is null | undefined;
/**
* Checks if value is null
* @param value - Value to check
* @returns Type guard boolean indicating value is null
*/
function isNull(value: unknown): value is null;
/**
* Checks if value is undefined
* @param value - Value to check
* @returns Type guard boolean indicating value is undefined
*/
function isUndefined(value: unknown): value is undefined;Usage Examples:
import { isNotNil, isNil, isNull, isUndefined } from 'es-toolkit/predicate';
// Filter out null/undefined values with type safety
const mixedArray: (string | null | undefined)[] = [
'hello', null, 'world', undefined, 'example'
];
const validStrings = mixedArray.filter(isNotNil);
// TypeScript knows validStrings is string[] (not (string | null | undefined)[])
console.log(validStrings); // ['hello', 'world', 'example']
// Safe property access
function processUser(user: { name?: string; email?: string } | null) {
if (isNotNil(user)) {
// TypeScript knows user is not null here
console.log(`Processing user: ${user.name || 'Unknown'}`);
if (isNotNil(user.email)) {
// TypeScript knows user.email is string here
console.log(`Email: ${user.email.toLowerCase()}`);
}
}
}
// Validation and error handling
function validateInput(value: unknown): string {
if (isNil(value)) {
throw new Error('Input cannot be null or undefined');
}
if (typeof value !== 'string') {
throw new Error('Input must be a string');
}
return value; // TypeScript knows this is string
}
// Specific null/undefined checks
const data = { value: null, count: undefined, name: 'test' };
console.log(isNull(data.value)); // true
console.log(isUndefined(data.count)); // true
console.log(isNil(data.name)); // falseFunctions for checking primitive JavaScript types with TypeScript type narrowing.
/**
* Checks if value is boolean
* @param value - Value to check
* @returns Type guard boolean indicating value is boolean
*/
function isBoolean(value: unknown): value is boolean;
/**
* Checks if value is string
* @param value - Value to check
* @returns Type guard boolean indicating value is string
*/
function isString(value: unknown): value is string;
/**
* Checks if value is function
* @param value - Value to check
* @returns Type guard boolean indicating value is function
*/
function isFunction(value: unknown): value is (...args: any[]) => any;
/**
* Checks if value is symbol
* @param value - Value to check
* @returns Type guard boolean indicating value is symbol
*/
function isSymbol(value: unknown): value is symbol;
/**
* Checks if value is primitive (string, number, boolean, symbol, null, undefined)
* @param value - Value to check
* @returns Boolean indicating if value is primitive
*/
function isPrimitive(value: unknown): boolean;Usage Examples:
import { isBoolean, isString, isFunction, isSymbol, isPrimitive } from 'es-toolkit/predicate';
// Dynamic type checking with type safety
function processValue(value: unknown) {
if (isString(value)) {
// TypeScript knows value is string here
console.log(`String length: ${value.length}`);
return value.toUpperCase();
}
if (isBoolean(value)) {
// TypeScript knows value is boolean here
console.log(`Boolean value: ${value ? 'true' : 'false'}`);
return !value;
}
if (isFunction(value)) {
// TypeScript knows value is function here
console.log('Executing function...');
return value();
}
return value;
}
// Form validation
function validateFormField(field: unknown): string | null {
if (!isString(field)) {
return 'Field must be a string';
}
if (field.trim().length === 0) {
return 'Field cannot be empty';
}
return null; // Valid
}
// Event handler type checking
function addEventListener(element: Element, event: string, handler: unknown) {
if (!isFunction(handler)) {
throw new Error('Event handler must be a function');
}
element.addEventListener(event, handler);
}
// Symbol processing
const symbols = [Symbol('a'), 'string', Symbol('b'), 42];
const symbolsOnly = symbols.filter(isSymbol);
// TypeScript knows symbolsOnly is symbol[]
// Primitive vs object distinction
function serializeValue(value: unknown): string {
if (isPrimitive(value)) {
return String(value);
} else {
return JSON.stringify(value);
}
}Functions for checking various object types including built-in objects.
/**
* Checks if value is plain object (not array, function, Date, etc.)
* @param value - Value to check
* @returns Type guard boolean indicating value is plain object
*/
function isPlainObject(value: unknown): value is Record<PropertyKey, any>;
/**
* Checks if value is Date object
* @param value - Value to check
* @returns Type guard boolean indicating value is Date
*/
function isDate(value: unknown): value is Date;
/**
* Checks if value is RegExp object
* @param value - Value to check
* @returns Type guard boolean indicating value is RegExp
*/
function isRegExp(value: unknown): value is RegExp;
/**
* Checks if value is Error object
* @param value - Value to check
* @returns Type guard boolean indicating value is Error
*/
function isError(value: unknown): value is Error;Usage Examples:
import { isPlainObject, isDate, isRegExp, isError } from 'es-toolkit/predicate';
// Safe object property access
function mergeConfig(userConfig: unknown, defaultConfig: object) {
if (!isPlainObject(userConfig)) {
console.warn('User config is not a plain object, using defaults');
return defaultConfig;
}
// TypeScript knows userConfig is Record<PropertyKey, any> here
return { ...defaultConfig, ...userConfig };
}
// Date validation and formatting
function formatDate(value: unknown): string {
if (!isDate(value)) {
throw new Error('Expected Date object');
}
// TypeScript knows value is Date here
return value.toLocaleDateString();
}
// RegExp pattern validation
function validatePattern(pattern: unknown): RegExp {
if (isRegExp(pattern)) {
// TypeScript knows pattern is RegExp here
return pattern;
}
if (isString(pattern)) {
return new RegExp(pattern);
}
throw new Error('Pattern must be RegExp or string');
}
// Error handling and logging
function logError(error: unknown) {
if (isError(error)) {
// TypeScript knows error is Error here
console.error(`Error: ${error.message}`);
console.error(`Stack: ${error.stack}`);
} else {
console.error('Unknown error:', error);
}
}
// Data processing with type safety
function processApiResponse(response: unknown) {
if (!isPlainObject(response)) {
throw new Error('Invalid API response format');
}
// Now TypeScript knows response is an object
const { data, metadata } = response;
if (isDate(data?.timestamp)) {
console.log(`Last updated: ${data.timestamp.toISOString()}`);
}
return response;
}Functions for checking JavaScript collection types like Map, Set, and their weak variants.
/**
* Checks if value is Map
* @param value - Value to check
* @returns Type guard boolean indicating value is Map
*/
function isMap(value: unknown): value is Map<any, any>;
/**
* Checks if value is Set
* @param value - Value to check
* @returns Type guard boolean indicating value is Set
*/
function isSet(value: unknown): value is Set<any>;
/**
* Checks if value is WeakMap
* @param value - Value to check
* @returns Type guard boolean indicating value is WeakMap
*/
function isWeakMap(value: unknown): value is WeakMap<any, any>;
/**
* Checks if value is WeakSet
* @param value - Value to check
* @returns Type guard boolean indicating value is WeakSet
*/
function isWeakSet(value: unknown): value is WeakSet<any>;Usage Examples:
import { isMap, isSet, isWeakMap, isWeakSet } from 'es-toolkit/predicate';
// Collection serialization
function serializeCollection(collection: unknown): any {
if (isMap(collection)) {
// TypeScript knows collection is Map here
return {
type: 'Map',
entries: Array.from(collection.entries())
};
}
if (isSet(collection)) {
// TypeScript knows collection is Set here
return {
type: 'Set',
values: Array.from(collection.values())
};
}
return collection;
}
// Cache implementation detection
function getCacheSize(cache: unknown): number {
if (isMap(cache) || isSet(cache)) {
// TypeScript knows cache has .size property
return cache.size;
}
if (isWeakMap(cache) || isWeakSet(cache)) {
// Weak collections don't have size property
return -1; // Size unknown
}
return 0;
}
// Collection utilities
function clearCollection(collection: unknown): void {
if (isMap(collection) || isSet(collection)) {
collection.clear();
console.log('Collection cleared');
} else if (isWeakMap(collection) || isWeakSet(collection)) {
console.log('Cannot clear weak collection programmatically');
} else {
console.log('Not a collection type');
}
}
// Type-safe collection operations
function addToCollection<T>(collection: unknown, item: T): boolean {
if (isSet(collection)) {
collection.add(item);
return true;
}
if (isMap(collection) && typeof item === 'object' && item !== null) {
// Assume item has key-value structure for Map
const entries = Object.entries(item);
entries.forEach(([key, value]) => collection.set(key, value));
return true;
}
return false;
}Functions for checking array-like structures and binary data types.
/**
* Checks if value is ArrayBuffer
* @param value - Value to check
* @returns Type guard boolean indicating value is ArrayBuffer
*/
function isArrayBuffer(value: unknown): value is ArrayBuffer;
/**
* Checks if value is TypedArray (Int8Array, Uint8Array, etc.)
* @param value - Value to check
* @returns Type guard boolean indicating value is TypedArray
*/
function isTypedArray(value: unknown): value is TypedArray;
/**
* Checks if value is Buffer (Node.js Buffer)
* @param value - Value to check
* @returns Type guard boolean indicating value is Buffer
*/
function isBuffer(value: unknown): value is Buffer;
/**
* Checks if value is valid array-like length
* @param value - Value to check
* @returns Type guard boolean indicating value is valid length
*/
function isLength(value: unknown): value is number;Usage Examples:
import { isArrayBuffer, isTypedArray, isBuffer, isLength } from 'es-toolkit/predicate';
// Binary data processing
function processBinaryData(data: unknown): Uint8Array {
if (isArrayBuffer(data)) {
// TypeScript knows data is ArrayBuffer here
return new Uint8Array(data);
}
if (isTypedArray(data)) {
// TypeScript knows data is TypedArray here
return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
}
if (isBuffer(data)) {
// TypeScript knows data is Buffer here (Node.js)
return new Uint8Array(data);
}
throw new Error('Expected binary data type');
}
// File handling in different environments
function getDataSize(data: unknown): number {
if (isArrayBuffer(data)) {
return data.byteLength;
}
if (isTypedArray(data)) {
return data.byteLength;
}
if (isBuffer(data)) {
return data.length;
}
return 0;
}
// Array-like validation
function createArrayLike(length: unknown, fillValue: any) {
if (!isLength(length)) {
throw new Error('Length must be a valid array length');
}
// TypeScript knows length is number here
return Array(length).fill(fillValue);
}
// Web API data conversion
function convertToBuffer(input: unknown): ArrayBuffer | null {
if (isArrayBuffer(input)) {
return input;
}
if (isTypedArray(input)) {
return input.buffer.slice(input.byteOffset, input.byteOffset + input.byteLength);
}
return null;
}Functions for checking browser-specific Web API types.
/**
* Checks if value is Blob
* @param value - Value to check
* @returns Type guard boolean indicating value is Blob
*/
function isBlob(value: unknown): value is Blob;
/**
* Checks if value is File
* @param value - Value to check
* @returns Type guard boolean indicating value is File
*/
function isFile(value: unknown): value is File;Usage Examples:
import { isBlob, isFile } from 'es-toolkit/predicate';
// File upload handling
function processUpload(fileData: unknown): Promise<string> {
if (isFile(fileData)) {
// TypeScript knows fileData is File here
console.log(`Processing file: ${fileData.name} (${fileData.size} bytes)`);
return fileData.text();
}
if (isBlob(fileData)) {
// TypeScript knows fileData is Blob here
console.log(`Processing blob: ${fileData.size} bytes, type: ${fileData.type}`);
return fileData.text();
}
throw new Error('Expected File or Blob');
}
// Drag and drop handling
function handleDrop(event: DragEvent) {
const items = event.dataTransfer?.items;
if (items) {
for (let i = 0; i < items.length; i++) {
const file = items[i].getAsFile();
if (isFile(file)) {
console.log(`Dropped file: ${file.name}`);
processUpload(file);
}
}
}
}
// Blob URL management
function createObjectURL(data: unknown): string | null {
if (isBlob(data) || isFile(data)) {
// TypeScript knows data is Blob or File here
return URL.createObjectURL(data);
}
return null;
}Functions for detecting the JavaScript execution environment.
/**
* Checks if running in browser environment
* @returns Boolean indicating if in browser
*/
function isBrowser(): boolean;
/**
* Checks if running in Node.js environment
* @returns Boolean indicating if in Node.js
*/
function isNode(): boolean;Usage Examples:
import { isBrowser, isNode } from 'es-toolkit/predicate';
// Environment-specific code
function getStorageAPI() {
if (isBrowser()) {
return {
get: (key: string) => localStorage.getItem(key),
set: (key: string, value: string) => localStorage.setItem(key, value),
remove: (key: string) => localStorage.removeItem(key)
};
}
if (isNode()) {
const fs = require('fs');
const path = require('path');
const storageFile = path.join(process.cwd(), 'storage.json');
return {
get: (key: string) => {
try {
const data = JSON.parse(fs.readFileSync(storageFile, 'utf8'));
return data[key] || null;
} catch {
return null;
}
},
set: (key: string, value: string) => {
let data = {};
try {
data = JSON.parse(fs.readFileSync(storageFile, 'utf8'));
} catch {}
data[key] = value;
fs.writeFileSync(storageFile, JSON.stringify(data));
},
remove: (key: string) => {
try {
const data = JSON.parse(fs.readFileSync(storageFile, 'utf8'));
delete data[key];
fs.writeFileSync(storageFile, JSON.stringify(data));
} catch {}
}
};
}
throw new Error('Unsupported environment');
}
// Polyfill loading
function loadPolyfills() {
if (isBrowser() && !window.fetch) {
// Load fetch polyfill for older browsers
console.log('Loading fetch polyfill...');
}
if (isNode() && !global.fetch) {
// Use node-fetch in Node.js environment
console.log('Setting up fetch for Node.js...');
}
}
// Logging configuration
function setupLogger() {
if (isBrowser()) {
return {
log: console.log,
error: console.error,
warn: console.warn
};
}
if (isNode()) {
const util = require('util');
return {
log: (msg: any) => process.stdout.write(util.format(msg) + '\n'),
error: (msg: any) => process.stderr.write(util.format(msg) + '\n'),
warn: (msg: any) => process.stderr.write('WARNING: ' + util.format(msg) + '\n')
};
}
return { log: () => {}, error: () => {}, warn: () => {} };
}Functions for checking asynchronous types and operations.
/**
* Checks if value is Promise
* @param value - Value to check
* @returns Type guard boolean indicating value is Promise
*/
function isPromise(value: unknown): value is Promise<any>;Usage Examples:
import { isPromise } from 'es-toolkit/predicate';
// Async/sync function handling
async function processResult<T>(result: T | Promise<T>): Promise<T> {
if (isPromise(result)) {
// TypeScript knows result is Promise<T> here
console.log('Awaiting promise...');
return await result;
}
// TypeScript knows result is T here
console.log('Using synchronous result');
return result;
}
// Function wrapper that handles both sync and async
function wrapFunction<T extends (...args: any[]) => any>(fn: T) {
return (...args: Parameters<T>): Promise<Awaited<ReturnType<T>>> => {
const result = fn(...args);
if (isPromise(result)) {
return result;
}
return Promise.resolve(result);
};
}
// Example usage
const syncFn = (x: number) => x * 2;
const asyncFn = async (x: number) => x * 2;
const wrappedSync = wrapFunction(syncFn);
const wrappedAsync = wrapFunction(asyncFn);
// Both return promises now
wrappedSync(5).then(console.log); // 10
wrappedAsync(5).then(console.log); // 10Functions for validating JSON-serializable data structures.
/**
* Checks if string is valid JSON
* @param value - String to check
* @returns Boolean indicating if string is valid JSON
*/
function isJSON(value: string): boolean;
/**
* Checks if value is JSON-serializable
* @param value - Value to check
* @returns Type guard boolean indicating value is JSON-serializable
*/
function isJSONValue(value: unknown): value is JSONValue;
/**
* Checks if value is JSON object
* @param value - Value to check
* @returns Type guard boolean indicating value is JSON object
*/
function isJSONObject(value: unknown): value is JSONObject;
/**
* Checks if value is JSON array
* @param value - Value to check
* @returns Type guard boolean indicating value is JSON array
*/
function isJSONArray(value: unknown): value is JSONArray;
type JSONValue = string | number | boolean | null | JSONObject | JSONArray;
type JSONObject = { [key: string]: JSONValue };
type JSONArray = JSONValue[];Usage Examples:
import { isJSON, isJSONValue, isJSONObject, isJSONArray } from 'es-toolkit/predicate';
// Safe JSON parsing
function safeParseJSON(text: string): any {
if (!isJSON(text)) {
throw new Error('Invalid JSON string');
}
return JSON.parse(text);
}
// API response validation
function validateApiResponse(response: unknown): JSONObject {
if (!isJSONObject(response)) {
throw new Error('API response must be a JSON object');
}
// TypeScript knows response is JSONObject here
return response;
}
// Data serialization safety
function safeStringify(data: unknown): string {
if (!isJSONValue(data)) {
throw new Error('Data is not JSON-serializable');
}
// TypeScript knows data is JSON-serializable here
return JSON.stringify(data);
}
// Array processing
function processJSONArray(data: unknown): any[] {
if (!isJSONArray(data)) {
throw new Error('Expected JSON array');
}
// TypeScript knows data is JSONArray here
return data.map(item => {
if (isJSONObject(item)) {
return { ...item, processed: true };
}
return item;
});
}
// Configuration validation
function validateConfig(config: unknown) {
if (isJSONObject(config)) {
// Validate required properties
const { database, server } = config;
if (isJSONObject(database) && isJSONObject(server)) {
return { database, server };
}
}
throw new Error('Invalid configuration format');
}Functions for deep equality checking with customization options.
/**
* Performs deep equality check
* @param a - First value to compare
* @param b - Second value to compare
* @returns Boolean indicating if values are deeply equal
*/
function isEqual(a: any, b: any): boolean;
/**
* Deep equality check with custom comparator
* @param a - First value to compare
* @param b - Second value to compare
* @param customizer - Optional custom comparison function
* @returns Boolean indicating if values are deeply equal
*/
function isEqualWith(
a: any,
b: any,
customizer?: (a: any, b: any) => boolean | undefined
): boolean;Usage Examples:
import { isEqual, isEqualWith } from 'es-toolkit/predicate';
// Deep object comparison
const obj1 = {
user: { name: 'Alice', age: 30 },
settings: { theme: 'dark', notifications: true }
};
const obj2 = {
user: { name: 'Alice', age: 30 },
settings: { theme: 'dark', notifications: true }
};
const obj3 = {
user: { name: 'Alice', age: 31 },
settings: { theme: 'dark', notifications: true }
};
console.log(isEqual(obj1, obj2)); // true
console.log(isEqual(obj1, obj3)); // false
// Array comparison
const arr1 = [1, [2, 3], { a: 4 }];
const arr2 = [1, [2, 3], { a: 4 }];
console.log(isEqual(arr1, arr2)); // true
// Custom equality with tolerance
function approximateEqual(a: any, b: any): boolean | undefined {
if (typeof a === 'number' && typeof b === 'number') {
return Math.abs(a - b) < 0.001;
}
return undefined; // Use default comparison
}
const point1 = { x: 1.0001, y: 2.0002 };
const point2 = { x: 1.0000, y: 2.0000 };
console.log(isEqual(point1, point2)); // false
console.log(isEqualWith(point1, point2, approximateEqual)); // true
// Date comparison with custom handling
function dateEqual(a: any, b: any): boolean | undefined {
if (isDate(a) && isDate(b)) {
return a.getTime() === b.getTime();
}
return undefined;
}
const date1 = new Date('2024-01-01');
const date2 = new Date('2024-01-01');
console.log(isEqualWith({ created: date1 }, { created: date2 }, dateEqual)); // trueimport { isNotNil, isString, isPlainObject } from 'es-toolkit/predicate';
function processUserData(data: unknown) {
if (isNotNil(data) && isPlainObject(data)) {
const { name, email } = data;
if (isString(name) && isString(email)) {
return { name: name.trim(), email: email.toLowerCase() };
}
}
throw new Error('Invalid user data');
}import { isNotNil, isString, isFunction } from 'es-toolkit/predicate';
const mixedArray: unknown[] = [
'hello', null, () => 'function', undefined, 'world', 42
];
const strings = mixedArray.filter(isString); // string[]
const functions = mixedArray.filter(isFunction); // ((...args: any[]) => any)[]
const nonNil = mixedArray.filter(isNotNil); // Exclude<unknown, null | undefined>[]Install with Tessl CLI
npx tessl i tessl/npm-es-toolkit