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

advanced-types.mddocs/

Advanced Type Checking

Advanced utilities for function detection, primitive checking, iterable validation, and composite type checking. These functions provide higher-level type analysis capabilities.

Capabilities

Function Detection

Returns whether the payload is a function (regular or async).

/**
 * Returns whether the payload is a function (regular or async)
 * @param payload - Value to check
 * @returns Type guard indicating if payload is function
 */
function isFunction(payload: unknown): payload is AnyFunction;

type AnyFunction = (...args: any[]) => any;
type AnyAsyncFunction = (...args: unknown[]) => Promise<unknown>;

Usage Examples:

import { isFunction } from "is-what";

// Regular functions
isFunction(function() {}); // true
isFunction(() => {}); // true
isFunction(console.log); // true

// Async functions
isFunction(async function() {}); // true
isFunction(async () => {}); // true

// Methods
class MyClass {
  method() {}
}
const obj = new MyClass();
isFunction(obj.method); // true

// Not functions
isFunction("function"); // false
isFunction({}); // false
isFunction(null); // false

if (isFunction(callback)) {
  // TypeScript knows callback is a function
  const result = callback(arg1, arg2);
}

// Practical usage
function executeCallback(callback: unknown, ...args: unknown[]) {
  if (isFunction(callback)) {
    return callback(...args);
  }
  
  throw new Error("Callback must be a function");
}

// Higher-order function validation
function createValidator(validator: unknown) {
  if (!isFunction(validator)) {
    throw new Error("Validator must be a function");
  }
  
  return (value: unknown) => validator(value);
}

Primitive Type Checking

Returns whether the payload is a primitive type (Boolean, Null, Undefined, Number, String, Symbol, or BigInt).

/**
 * Returns whether the payload is a primitive type 
 * (Boolean | Null | Undefined | Number | String | Symbol | BigInt)
 * @param payload - Value to check
 * @returns Type guard indicating if payload is primitive
 */
function isPrimitive(
  payload: unknown
): payload is boolean | null | undefined | number | string | symbol | bigint;

Usage Examples:

import { isPrimitive } from "is-what";

// Primitive values
isPrimitive(true); // true
isPrimitive(42); // true
isPrimitive("hello"); // true
isPrimitive(null); // true
isPrimitive(undefined); // true
isPrimitive(Symbol("test")); // true
isPrimitive(123n); // true

// Non-primitive values
isPrimitive({}); // false
isPrimitive([]); // false
isPrimitive(new Date()); // false
isPrimitive(() => {}); // false

// Practical usage
function serializeValue(value: unknown) {
  if (isPrimitive(value)) {
    // Safe to serialize directly
    return JSON.stringify(value);
  }
  
  // Handle complex objects
  return JSON.stringify(value, null, 2);
}

// Type categorization
function categorizeValue(value: unknown) {
  if (isPrimitive(value)) {
    return {
      category: "primitive",
      type: typeof value,
      value: value
    };
  }
  
  return {
    category: "object",
    type: value?.constructor?.name || "Object",
    value: value
  };
}

Iterable Detection

Returns whether the payload is an iterable (regular or async).

/**
 * Returns whether the payload is an iterable (regular or async)
 * @param payload - Value to check
 * @returns Type guard indicating if payload is iterable
 */
function isIterable(payload: unknown): payload is Iterable<unknown>;

Usage Examples:

import { isIterable } from "is-what";

// Iterable types
isIterable([]); // true (arrays)
isIterable("hello"); // true (strings)
isIterable(new Set([1, 2, 3])); // true
isIterable(new Map([["a", 1]])); // true
isIterable(function*() { yield 1; }()); // true (generators)

// Custom iterables
const customIterable = {
  *[Symbol.iterator]() {
    yield 1;
    yield 2;
    yield 3;
  }
};
isIterable(customIterable); // true

// Not iterable
isIterable({}); // false
isIterable(123); // false
isIterable(null); // false

if (isIterable(collection)) {
  // TypeScript knows collection is iterable
  for (const item of collection) {
    console.log(item);
  }
  
  // Can use spread operator
  const array = [...collection];
}

// Practical usage
function processIterable(input: unknown) {
  if (isIterable(input)) {
    const results = [];
    for (const item of input) {
      results.push(processItem(item));
    }
    return results;
  }
  
  throw new Error("Input must be iterable");
}

// Safe iteration
function safeForEach(collection: unknown, callback: (item: unknown) => void) {
  if (isIterable(collection) && isFunction(callback)) {
    for (const item of collection) {
      callback(item);
    }
  }
}

Combined Advanced Type Patterns

import { 
  isFunction, 
  isPrimitive, 
  isIterable, 
  isOneOf,
  isNull,
  isUndefined
} from "is-what";

// Create nullish checker using factory function
const isNullOrUndefined = isOneOf(isNull, isUndefined);

function analyzeAdvancedType(value: unknown) {
  if (isNullOrUndefined(value)) {
    return `Nullish: ${value}`;
  }
  
  if (isPrimitive(value)) {
    return `Primitive ${typeof value}: ${value}`;
  }
  
  if (isFunction(value)) {
    return `Function: ${value.name || 'anonymous'} (${value.length} params)`;
  }
  
  if (isIterable(value)) {
    const type = value.constructor?.name || "Iterable";
    return `Iterable ${type}`;
  }
  
  return `Non-iterable object: ${value.constructor?.name || "Object"}`;
}

// Comprehensive data processor
function processAnyData(data: unknown) {
  // Handle nullish values
  if (isNullOrUndefined(data)) {
    return { type: "nullish", value: data, processed: null };
  }
  
  // Handle primitives
  if (isPrimitive(data)) {
    return {
      type: "primitive",
      dataType: typeof data,
      value: data,
      processed: data
    };
  }
  
  // Handle functions
  if (isFunction(data)) {
    return {
      type: "function",
      name: data.name || "anonymous",
      paramCount: data.length,
      processed: data.toString()
    };
  }
  
  // Handle iterables
  if (isIterable(data)) {
    const items = Array.from(data);
    return {
      type: "iterable",
      constructor: data.constructor?.name || "Iterable",
      length: items.length,
      processed: items
    };
  }
  
  // Handle other objects
  return {
    type: "object",
    constructor: data?.constructor?.name || "Object",
    processed: data
  };
}

// Type-safe utility functions
function createSafeMapper(mapperFn: unknown) {
  if (!isFunction(mapperFn)) {
    throw new Error("Mapper must be a function");
  }
  
  return (collection: unknown) => {
    if (!isIterable(collection)) {
      throw new Error("Collection must be iterable");
    }
    
    const results = [];
    for (const item of collection) {
      results.push(mapperFn(item));
    }
    return results;
  };
}

function safeFunctionCall(fn: unknown, ...args: unknown[]) {
  if (isFunction(fn)) {
    try {
      return { success: true, result: fn(...args) };
    } catch (error) {
      return { success: false, error };
    }
  }
  
  return { success: false, error: "Not a function" };
}

// Example usage
analyzeAdvancedType(null); // "Nullish: null"
analyzeAdvancedType(42); // "Primitive number: 42"
analyzeAdvancedType(console.log); // "Function: log (1 params)"
analyzeAdvancedType([1, 2, 3]); // "Iterable Array"
analyzeAdvancedType({}); // "Non-iterable object: Object"

const result = processAnyData("hello world");
// Returns: {
//   type: "primitive",
//   dataType: "string",
//   value: "hello world",
//   processed: "hello world"
// }

const mapper = createSafeMapper((x: any) => x * 2);
const doubled = mapper([1, 2, 3]); // [2, 4, 6]

Types

type AnyFunction = (...args: any[]) => any;
type AnyAsyncFunction = (...args: unknown[]) => Promise<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