or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

array-operations.mdfunction-utilities.mdindex.mdmath-operations.mdobject-operations.mdpromise-utilities.mdstring-operations.mdtime-performance.mdtype-guards.md
tile.json

type-guards.mddocs/

Type Guards & Validation

Type checking utilities and type guards providing runtime validation, type narrowing, and safe type checking operations.

Capabilities

Primitive Type Guards

Type guards for checking JavaScript primitive types with TypeScript type narrowing.

/**
 * Check if value is defined (not undefined)
 * @param val - Value to check
 * @returns True if value is not undefined
 */
function isDef<T = any>(val?: T): val is T;

/**
 * Check if value is boolean
 * @param val - Value to check
 * @returns True if value is boolean
 */
function isBoolean(val: any): val is boolean;

/**
 * Check if value is function
 * @param val - Value to check
 * @returns True if value is function
 */
function isFunction<T extends Function = Function>(val: any): val is T;

/**
 * Check if value is number
 * @param val - Value to check
 * @returns True if value is number
 */
function isNumber(val: any): val is number;

/**
 * Check if value is string
 * @param val - Value to check
 * @returns True if value is string
 */
function isString(val: unknown): val is string;

/**
 * Check if value is plain object
 * @param val - Value to check
 * @returns True if value is plain object
 */
function isObject(val: any): val is object;

/**
 * Check if value is undefined
 * @param val - Value to check
 * @returns True if value is undefined
 */
function isUndefined(val: any): val is undefined;

/**
 * Check if value is null
 * @param val - Value to check
 * @returns True if value is null
 */
function isNull(val: any): val is null;

Usage Examples:

import { isDef, isBoolean, isNumber, isString, isObject } from "@antfu/utils";

function processValue(value: unknown) {
  if (isString(value)) {
    return value.toUpperCase(); // TypeScript knows value is string
  }
  
  if (isNumber(value)) {
    return value * 2; // TypeScript knows value is number
  }
  
  if (isObject(value)) {
    return Object.keys(value); // TypeScript knows value is object
  }
  
  return null;
}

// Safe optional value handling
function handleOptional(val?: string) {
  if (isDef(val)) {
    console.log(val.length); // TypeScript knows val is string (not undefined)
  }
}

// Type-safe function checking
function maybeCall(fn: unknown, ...args: any[]) {
  if (isFunction(fn)) {
    return fn(...args); // TypeScript knows fn is callable
  }
  return undefined;
}

Complex Type Guards

Type guards for more complex JavaScript types and objects.

/**
 * Check if value is RegExp
 * @param val - Value to check
 * @returns True if value is RegExp
 */
function isRegExp(val: any): val is RegExp;

/**
 * Check if value is Date
 * @param val - Value to check
 * @returns True if value is Date
 */
function isDate(val: any): val is Date;

/**
 * Check if value is primitive (string, number, boolean, symbol, bigint, null, undefined)
 * @param val - Value to check
 * @returns True if value is primitive
 */
function isPrimitive(val: any): val is string | number | boolean | symbol | bigint | null | undefined;

Usage Examples:

import { isRegExp, isDate, isPrimitive } from "@antfu/utils";

function processInput(input: unknown) {
  if (isDate(input)) {
    return input.toISOString(); // TypeScript knows input is Date
  }
  
  if (isRegExp(input)) {
    return input.source; // TypeScript knows input is RegExp
  }
  
  if (isPrimitive(input)) {
    return String(input); // Safe to convert primitives to string
  }
  
  return "Complex object";
}

// Pattern matching with type guards
function formatValue(value: unknown): string {
  if (isDate(value)) return value.toLocaleDateString();
  if (isRegExp(value)) return `Pattern: ${value.source}`;
  if (isPrimitive(value)) return String(value);
  return "[Object]";
}

Environment Type Guards

Type guards for checking runtime environment characteristics.

/**
 * Check if value is Window object (browser only)
 * @param val - Value to check
 * @returns True if value is Window object
 */
function isWindow(val: any): boolean;

/**
 * Constant indicating if running in browser environment
 */
const isBrowser: boolean;

Usage Examples:

import { isWindow, isBrowser } from "@antfu/utils";

// Environment-aware code
if (isBrowser) {
  // Browser-specific code
  const element = document.getElementById('app');
  
  if (isWindow(globalThis)) {
    console.log('Running in browser window context');
  }
} else {
  // Node.js or other environment
  console.log('Running in non-browser environment');
}

// Safe DOM manipulation
function setupUI() {
  if (isBrowser && typeof document !== 'undefined') {
    const button = document.createElement('button');
    button.textContent = 'Click me';
    document.body.appendChild(button);
  }
}

Nullish Value Filtering

Type guards specifically designed for filtering out null, undefined, and falsy values.

/**
 * Type guard to filter out null-ish values
 * @param v - Value to check
 * @returns True if value is not null or undefined
 */
function notNullish<T>(v: T | null | undefined): v is NonNullable<T>;

/**
 * Type guard to filter out null values
 * @param v - Value to check
 * @returns True if value is not null
 */
function noNull<T>(v: T | null): v is Exclude<T, null>;

/**
 * Type guard to filter out undefined values
 * @param v - Value to check
 * @returns True if value is not undefined
 */
function notUndefined<T>(v: T): v is Exclude<T, undefined>;

/**
 * Type guard to filter out falsy values
 * @param v - Value to check
 * @returns True if value is truthy
 */
function isTruthy<T>(v: T): v is NonNullable<T>;

Usage Examples:

import { notNullish, noNull, notUndefined, isTruthy } from "@antfu/utils";

// Filter arrays with type safety
const mixedArray: (string | null | undefined)[] = ["hello", null, "world", undefined, ""];

// Remove null and undefined
const definedValues = mixedArray.filter(notNullish);
// Type: string[], values: ["hello", "world", ""]

// Remove only null values
const notNullValues = mixedArray.filter(noNull);
// Type: (string | undefined)[], values: ["hello", "world", undefined, ""]

// Remove only undefined values
const notUndefinedValues = mixedArray.filter(notUndefined);
// Type: (string | null)[], values: ["hello", null, "world", ""]

// Remove all falsy values
const truthyValues = mixedArray.filter(isTruthy);
// Type: string[], values: ["hello", "world"]

// Safe optional chaining alternative
function processUser(user: { name?: string; email?: string | null }) {
  const fields = [user.name, user.email].filter(notNullish);
  // fields is guaranteed to be string[]
  return fields.map(field => field.toUpperCase());
}

// Array processing with type narrowing
function processItems<T>(items: (T | null | undefined)[]): T[] {
  return items
    .filter(notNullish) // Remove null/undefined
    .filter(isTruthy);  // Remove remaining falsy values
}

Base Utilities

Core utility functions for assertions, type inspection, and basic operations.

/**
 * Assert a condition is true, throwing an error with message if not
 * @param condition - Condition to assert
 * @param message - Error message if assertion fails
 * @throws Error if condition is false
 */
function assert(condition: boolean, message: string): asserts condition;

/**
 * Get the string representation of a value using Object.prototype.toString
 * @param v - Value to get string representation of
 * @returns String representation like "[object Array]"
 */
function toString(v: any): string;

/**
 * Get the type name of a value
 * @param v - Value to get type name for
 * @returns Type name as string (e.g., "array", "object", "string")
 */
function getTypeName(v: any): string;

/**
 * No-operation function that does nothing
 */
function noop(): void;

Usage Examples:

import { assert, toString, getTypeName, noop } from "@antfu/utils";

// Assertions in code
function divide(a: number, b: number): number {
  assert(b !== 0, "Division by zero is not allowed");
  return a / b;
}

// Type inspection
const typeString = toString([1, 2, 3]); // "[object Array]"
const typeName = getTypeName([1, 2, 3]); // "array"
const objType = getTypeName({ a: 1 }); // "object"
const primitiveType = getTypeName("hello"); // "string"

// No-op placeholder
let callback: () => void = noop; // Safe default

function setupHandler(handler: () => void = noop) {
  // Use noop as default to avoid null checks
  document.addEventListener('click', handler);
}

// Type-safe assertions
function processUser(user: unknown): User {
  assert(typeof user === 'object' && user !== null, 'User must be an object');
  assert('id' in user, 'User must have an id');
  return user as User;
}

// Debug type inspection
function debugValue(value: unknown): void {
  console.log(`Value: ${value}`);
  console.log(`Type: ${getTypeName(value)}`);
  console.log(`ToString: ${toString(value)}`);
}

Deep Equality

Advanced equality checking for complex data structures.

/**
 * Deep equality comparison for complex objects and arrays
 * @param value1 - First value to compare
 * @param value2 - Second value to compare
 * @returns True if values are deeply equal
 */
function isDeepEqual(value1: any, value2: any): boolean;

Usage Examples:

import { isDeepEqual } from "@antfu/utils";

// Compare primitive values
console.log(isDeepEqual(1, 1)); // true
console.log(isDeepEqual("hello", "hello")); // true
console.log(isDeepEqual(1, "1")); // false

// Compare arrays
const arr1 = [1, 2, { a: 3 }];
const arr2 = [1, 2, { a: 3 }];
const arr3 = [1, 2, { a: 4 }];

console.log(isDeepEqual(arr1, arr2)); // true
console.log(isDeepEqual(arr1, arr3)); // false

// Compare objects
const obj1 = { name: "Alice", details: { age: 30, city: "NYC" } };
const obj2 = { name: "Alice", details: { age: 30, city: "NYC" } };
const obj3 = { name: "Alice", details: { age: 30, city: "LA" } };

console.log(isDeepEqual(obj1, obj2)); // true
console.log(isDeepEqual(obj1, obj3)); // false

// Useful for React/Vue optimization
function shouldUpdateComponent(prevProps: any, nextProps: any) {
  return !isDeepEqual(prevProps, nextProps);
}

// State comparison in reducers
function updateState(currentState: any, newState: any) {
  if (isDeepEqual(currentState, newState)) {
    return currentState; // No change, return same reference
  }
  return newState;
}