CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-is-what

JavaScript and TypeScript type checking utility functions providing precise type validation with automatic type narrowing.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

object-types.mddocs/

Object Type Checking

Comprehensive object type validation including plain object detection, empty/full object checks, and object-like detection. These functions provide crucial distinctions between different types of objects in JavaScript.

Capabilities

Object Type Checking

Returns whether the payload is a plain JavaScript object. This is an alias for isPlainObject.

/**
 * Returns whether the payload is a plain JavaScript object (excluding special classes 
 * or objects with other prototypes). This is an alias for isPlainObject.
 * @param payload - Value to check
 * @returns Type guard indicating if payload is plain object
 */
function isObject(payload: unknown): payload is PlainObject;

Usage Examples:

import { isObject } from "is-what";

// Plain objects
isObject({}); // true
isObject({ name: "John", age: 30 }); // true

// Not plain objects
isObject([]); // false (array)
isObject(new Date()); // false (Date instance)
isObject(new Map()); // false (Map instance)
isObject(/regex/); // false (RegExp instance)
isObject(() => {}); // false (function)
isObject(null); // false (null)
isObject("string"); // false
isObject(123); // false

if (isObject(data)) {
  // TypeScript knows data is PlainObject
  console.log(Object.keys(data)); // Safe to use Object methods
}

Plain Object Detection

Returns whether the payload is a plain JavaScript object (excluding special classes or objects with other prototypes). This is one of the most important functions for distinguishing plain objects from class instances.

/**
 * Returns whether the payload is a plain JavaScript object (excluding special classes 
 * or objects with other prototypes)
 * @param payload - Value to check
 * @returns Type guard indicating if payload is plain object
 */
function isPlainObject(payload: unknown): payload is PlainObject;

type PlainObject = { [key in string | number | symbol]: unknown };

Usage Examples:

import { isPlainObject } from "is-what";

// Plain objects
isPlainObject({}); // true
isPlainObject({ name: "John", age: 30 }); // true
isPlainObject(Object.create(null)); // true (no prototype)
isPlainObject(Object.create(Object.prototype)); // true

// Not plain objects
isPlainObject([]); // false (array)
isPlainObject(new Date()); // false (Date instance)
isPlainObject(new Map()); // false (Map instance)
isPlainObject(/regex/); // false (RegExp instance)
isPlainObject(() => {}); // false (function)

class MyClass {
  constructor(public name: string) {}
}
isPlainObject(new MyClass("test")); // false (class instance)

// Practical usage
function mergeConfig(userConfig: unknown, defaultConfig: object) {
  if (isPlainObject(userConfig)) {
    // Safe to merge - it's a plain object
    return { ...defaultConfig, ...userConfig };
  }
  
  throw new Error("Config must be a plain object");
}

// JSON-like validation
function isJsonSerializable(value: unknown): boolean {
  if (isPlainObject(value)) {
    // Check all properties recursively
    return Object.values(value).every(isJsonSerializable);
  }
  // Add other JSON-compatible type checks...
  return false;
}

Any Object Detection

Returns whether the payload is any kind of object with Object prototype (but not arrays, dates, etc.).

/**
 * Returns whether the payload is any kind of object (including special classes or objects with
 * different prototypes)
 * @param payload - Value to check
 * @returns Type guard indicating if payload is any object
 */
function isAnyObject(payload: unknown): payload is PlainObject;

Usage Examples:

import { isAnyObject } from "is-what";

isAnyObject({}); // true
isAnyObject([]); // true
isAnyObject(new Date()); // true
isAnyObject(new Map()); // true
isAnyObject(/regex/); // true
isAnyObject(() => {}); // true
isAnyObject(null); // false
isAnyObject("string"); // false
isAnyObject(123); // false

// Useful for broad object checks
function processObjectData(input: unknown) {
  if (isAnyObject(input)) {
    // Any object type can be processed
    console.log("Processing object:", Object.keys(input));
  }
}

Object-Like Detection

Returns whether the payload is an object like a type passed in generics. This is a generic function for type-safe object checking.

/**
 * Returns whether the payload is an object like a type passed in < >
 * Usage: isObjectLike<{id: any}>(payload) // will make sure it's an object and has an `id` prop.
 * @template T This must be passed in < >
 * @param payload - Value to check
 * @returns Type guard indicating if payload matches the generic type
 */
function isObjectLike<T extends PlainObject>(payload: unknown): payload is T;

Usage Examples:

import { isObjectLike } from "is-what";

// Generic type checking
interface User {
  id: string;
  name: string;
}

if (isObjectLike<User>(data)) {
  // TypeScript knows data has User shape, but doesn't validate properties
  // This is mainly for type assertion purposes
}

// More practical usage for ensuring object structure
function processUserData(input: unknown) {
  if (isObjectLike<{ id: string; name: string }>(input)) {
    // TypeScript knows input has id and name properties
    return `User: ${input.name} (${input.id})`;
  }
  
  throw new Error("Invalid user data structure");
}

Empty Object Checking

Returns whether the payload is an empty plain object with no enumerable properties.

/**
 * Returns whether the payload is an empty object (excluding special classes or objects 
 * with other prototypes)
 * @param payload - Value to check
 * @returns Type guard indicating if payload is empty plain object
 */
function isEmptyObject(payload: unknown): payload is { [K in string | symbol | number]: never };

Usage Examples:

import { isEmptyObject } from "is-what";

isEmptyObject({}); // true
isEmptyObject({ name: "John" }); // false
isEmptyObject([]); // false (not a plain object)
isEmptyObject(new Date()); // false (not a plain object)
isEmptyObject(null); // false
isEmptyObject(""); // false

// Practical usage
function validateConfigObject(config: unknown) {
  if (isEmptyObject(config)) {
    console.log("No configuration provided, using defaults");
    return getDefaultConfig();
  }
  
  // Process non-empty config
  return config;
}

// Combined with plain object check
function processUserInput(input: unknown) {
  if (isPlainObject(input)) {
    if (isEmptyObject(input)) {
      return { error: "Configuration cannot be empty" };
    }
    
    return { success: true, config: input };
  }
  
  return { error: "Input must be a plain object" };
}

Full Object Checking

Returns whether the payload is a plain object with at least one enumerable property.

/**
 * Returns whether the payload is a plain object with at least one property (excluding special classes or objects 
 * with other prototypes)
 * @param payload - Value to check
 * @returns Type guard indicating if payload is non-empty plain object
 */
function isFullObject(payload: unknown): payload is PlainObject;

Usage Examples:

import { isFullObject } from "is-what";

isFullObject({ name: "John" }); // true
isFullObject({ 0: "a", 1: "b" }); // true
isFullObject([1, 2, 3]); // false (not a plain object)
isFullObject({}); // false
isFullObject([]); // false
isFullObject(null); // false
isFullObject("string"); // false

// Validation pattern
function requireNonEmptyObject(obj: unknown, fieldName: string) {
  if (!isFullObject(obj)) {
    throw new Error(`${fieldName} must be a non-empty object`);
  }
  
  return obj;
}

Combined Object Validation Patterns

import { 
  isObject, 
  isPlainObject, 
  isAnyObject, 
  isEmptyObject, 
  isFullObject 
} from "is-what";

function analyzeObject(value: unknown) {
  if (!isObject(value)) {
    return "Not an object";
  }
  
  const characteristics = [];
  
  if (isPlainObject(value)) {
    characteristics.push("plain object");
  } else {
    characteristics.push("special object");
  }
  
  if (isEmptyObject(value)) {
    characteristics.push("empty");
  } else if (isFullObject(value)) {
    const keys = Object.keys(value);
    characteristics.push(`${keys.length} properties`);
  }
  
  return characteristics.join(", ");
}

// Object processing pipeline
function processObjectInput(input: unknown) {
  // Broad object check
  if (!isAnyObject(input)) {
    throw new Error("Input must be an object");
  }
  
  // Handle different object types
  if (isPlainObject(input)) {
    if (isEmptyObject(input)) {
      return { type: "plain", empty: true, processed: {} };
    }
    
    if (isFullObject(input)) {
      // Safe to iterate over properties
      const processed = Object.fromEntries(
        Object.entries(input).map(([key, value]) => [
          key, 
          typeof value === 'string' ? value.trim() : value
        ])
      );
      
      return { 
        type: "plain", 
        empty: false, 
        keys: Object.keys(input),
        processed 
      };
    }
  }
  
  // Handle special objects (arrays, dates, etc.)
  return {
    type: "special",
    constructor: input.constructor?.name || "Unknown",
    processed: input
  };
}

// Type-safe object operations
function safeObjectOperations(obj: unknown) {
  if (isPlainObject(obj)) {
    const keys = Object.keys(obj);
    const values = Object.values(obj);
    
    return {
      isPlain: true,
      isEmpty: isEmptyObject(obj),
      keyCount: keys.length,
      keys,
      values,
      entries: Object.entries(obj)
    };
  }
  
  if (isAnyObject(obj)) {
    return {
      isPlain: false,
      type: obj.constructor?.name || "Object",
      toString: obj.toString?.() || "[object Object]"
    };
  }
  
  return null;
}

// Example usage
analyzeObject({}); // "plain object, empty"
analyzeObject({ name: "John", age: 30 }); // "plain object, 2 properties"
analyzeObject([]); // "special object, empty"
analyzeObject([1, 2, 3]); // "special object, 3 properties"
analyzeObject(new Date()); // "special object, 0 properties"
analyzeObject("not object"); // "Not an object"

const result = processObjectInput({ name: "  John  ", age: 30 });
// Returns: {
//   type: "plain",
//   empty: false,
//   keys: ["name", "age"],
//   processed: { name: "John", age: 30 }
// }

Types

type PlainObject = { [key in string | number | symbol]: unknown };

docs

advanced-types.md

array-types.md

basic-types.md

builtin-types.md

generic-utils.md

index.md

number-validation.md

object-types.md

string-types.md

tile.json