npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@knighttower/type-check

v5.17.0

Published

typeCheck JS

Readme

typeCheck JS

A simple type checker for JavaScript

typeCheck JS is a JavaScript library designed for fast and efficient type checking. Inspired by gkz/type-check, this library aims to overcome the limitations and complexities associated with TypeScript. It offers a lightweight, memory-efficient, and easy-to-use solution for both basic and complex type-checking requirements.

release version NPM published


📚 Table of Contents


🔧 Installation

Via npm

npm i @knighttower/type-check
# or
yarn add @knighttower/type-check
# or
# as part of a monorepo
npm i knighttower 
# then import {typeCheck} from 'knighttower/type-check';

In the Browser

<script src="https://cdn.jsdelivr.net/npm/@knighttower/type-check@latest/dist/browser/typeCheck.min.js"></script>

<!-- OR as ESM -->
<script type="module">
  import { typeCheck } from 'https://esm.run/@knighttower/type-check@latest/index.js';
</script>

Note: by default the library is ESM, but other builds are available in the dist folder (CJS, UMD, IIFE, etc.)


📦 Files

| File | Size | | ---------------- | ----- | | /typeCheck.js | 8 KiB | | /typeCheck.js.br | 3 KiB | | /typeCheck.js.gz | 3 KiB |

You can also import from the /src folder for ESM + JS next, or from /index.js and /index.cjs.js as needed.


💡 Why typeCheck JS?

  1. Lightweight: Adds minimal overhead to your project (~6k GZip).
  2. Fast Performance: Micro Optimized for runtime operations.
  3. Ease of Use: Simple API and pattern syntax.
  4. No Compile Step: Works directly in vanilla JS.
  5. Complementary: Works alongside TypeScript for runtime enforcement.
  6. Supports: callbacks, custom messages, logs, and error throwing.
  7. Flexible: Supports piped types, optional keys, wildcard matching.
  8. Extensible: You can register custom test types.
  9. Fully Tested: Using Vitest for all cases.
  10. Documented: Full JSDoc for all major methods and patterns.

❓ What does it solve?

  • Enforces runtime type checking in production builds.
  • Helps validate user inputs, API data, and 3rd-party sources.
  • Avoids unnecessary adoption of TypeScript for small apps.
  • Solves the issue of type loss in runtime JS after TS transpilation.
  • Works directly in browsers or legacy JS environments.
  • Helps library authors enforce expected types at runtime.


🚫 What it doesn't solve

  • It doesn't stop bad programming decisions.

📋 API Reference

typeCheck()

Basic type validation with strict error throwing

typeCheck(valueToTest, typeExpression, options?)

Parameters:

  • valueToTest (any) - The value to validate
  • typeExpression (string) - The type pattern to match against
  • options (object|string, optional) - Configuration options

Returns: true on success, throws error on failure

Examples:

import { typeCheck } from '@knighttower/type-check';

// Basic types
typeCheck(123, 'number');        // ✅ passes
typeCheck('hello', 'string');    // ✅ passes
typeCheck(true, 'boolean');      // ✅ passes

// Will throw errors
typeCheck('hello', 'number');    // ❌ throws TypeError
typeCheck(123, 'string');       // ❌ throws TypeError

// Optional types
typeCheck(null, 'string?');      // ✅ passes (null/undefined allowed)
typeCheck(undefined, 'number?'); // ✅ passes
typeCheck('hello', 'string?');   // ✅ passes

// Union types
typeCheck(123, 'string|number'); // ✅ passes (either type allowed)
typeCheck('hi', 'string|number'); // ✅ passes

// Arrays
typeCheck([1, 2, 3], '[number]');           // ✅ all elements are numbers
typeCheck([1, 'hi', 3], '[number, string, number]'); // ✅ exact positions match

// Objects
typeCheck({ name: 'John', age: 30 }, '{name: string, age: number}'); // ✅
typeCheck({ x: 1, y: 2 }, '{any: number}');  // ✅ all values are numbers

// Custom error message
typeCheck(123, 'string', { error: 'Value must be a string!' });

// With callback for additional validation
typeCheck({ id: 1 }, '{id: number}', (result) => {
    console.log('Validation result:', result);
});

_typeCheck()

Advanced type validation with chainable methods

_typeCheck(valueToTest, typeExpression, options?)

Parameters:

  • Same as typeCheck() but returns a chainable object instead of throwing immediately

Chainable Methods:

  • .test() - Returns boolean result
  • .bool - Direct boolean property access
  • .log() - Logs validation details to console
  • .fail() - Throws error if validation fails
  • .return() - Returns the original value

Examples:

import { _typeCheck } from '@knighttower/type-check';

// Get boolean result without throwing
const isValid = _typeCheck(123, 'number').test(); // true

// Chain methods for debugging
_typeCheck({ name: 'John' }, '{name: string}')
    .log()      // logs validation details
    .fail()     // throws if invalid
    .return();  // returns original value

// Conditional validation
if (_typeCheck(userInput, 'string').test()) {
    // Safe to use userInput as string
    console.log(userInput.toUpperCase());
}

// Direct boolean access
const isNumber = _typeCheck(value, 'number').bool;

// Custom options
_typeCheck(data, 'object', {
    log: true,           // auto-log results
    fail: true,          // auto-fail on error
    callback: (result) => {
        console.log('Custom validation logic', result);
    }
});

validType()

Simple boolean validation without throwing errors

validType(valueToTest, typeExpression)

Parameters:

  • valueToTest (any) - The value to validate
  • typeExpression (string) - The type pattern to match against

Returns: boolean - true if valid, false if invalid

Examples:

import { validType } from '@knighttower/type-check';

// Safe validation for conditional logic
if (validType(userInput, 'string')) {
    // userInput is definitely a string
    processString(userInput);
} else {
    console.log('Invalid input type');
}

// Form validation
function validateForm(data) {
    const errors = [];
    
    if (!validType(data.email, 'string')) {
        errors.push('Email must be a string');
    }
    
    if (!validType(data.age, 'number')) {
        errors.push('Age must be a number');
    }
    
    if (!validType(data.preferences, '{theme: string, notifications: boolean}')) {
        errors.push('Invalid preferences object');
    }
    
    return errors;
}

// API response validation
function handleApiResponse(response) {
    if (validType(response, '{data: array, status: number}')) {
        return response.data;
    }
    throw new Error('Invalid API response format');
}

_tc()

Function wrapper with input parameter validation

_tc(typeExpressions, functionToWrap, options?)

Parameters:

  • typeExpressions (array) - Array of type patterns for each parameter
  • functionToWrap (function) - The function to wrap with validation
  • options (object, optional) - Configuration options

Returns: Wrapped function that validates inputs before execution

Examples:

import { _tc } from '@knighttower/type-check';

// Basic function wrapping
const greet = _tc(['string'], function(name) {
    return `Hello, ${name}!`;
});

greet('Alice');  // ✅ returns "Hello, Alice!"
greet(123);      // ❌ throws error

// Multiple parameters
const calculate = _tc(['number', 'number', 'string'], function(a, b, operation) {
    switch(operation) {
        case 'add': return a + b;
        case 'multiply': return a * b;
        default: return 0;
    }
});

calculate(5, 3, 'add');      // ✅ returns 8
calculate('5', 3, 'add');    // ❌ throws error

// With options
const processUser = _tc(
    ['{name: string, age: number}'],
    function(user) {
        return `Processing user: ${user.name}, age: ${user.age}`;
    },
    { 
        log: false,  // don't log by default
        fail: true,  // throw errors (default)
        error: 'Invalid user object provided'
    }
);

// Arrow functions
const multiply = _tc(['number', 'number'], (a, b) => a * b);

// Complex type validation
const createOrder = _tc(
    ['{items: [object], total: number, customer: {id: number, email: string}}'],
    function(orderData) {
        // Function implementation
        return { orderId: Date.now(), ...orderData };
    }
);

_tcx()

Function wrapper with input AND output validation

_tcx(typeExpressions, functionToWrap, options?)

Parameters:

  • typeExpressions (array) - Array of type patterns for each parameter
  • functionToWrap (function) - The function to wrap with validation
  • options (object, optional) - Configuration options including validOutput

Chainable Methods:

  • .log() - Log validation details
  • .fail() - Throw error if validation fails
  • .return() - Get the return value
  • .test() - Get boolean validation result

Examples:

import { _tcx } from '@knighttower/type-check';

// Function with return value validation
const getLength = _tcx(
    ['string'],
    (str) => str.length,
    { validOutput: 'number' }
);

const length = getLength('hello').return();  // 5
getLength(123);  // ❌ throws (invalid input)

// Complex example with chaining
const processData = _tcx(
    ['{data: array}'],
    function(input) {
        return {
            processed: true,
            count: input.data.length,
            summary: 'Data processed successfully'
        };
    },
    { 
        validOutput: '{processed: boolean, count: number, summary: string}',
        log: false
    }
);

const result = processData({ data: [1, 2, 3] })
    .log()      // logs validation details
    .fail()     // throws if validation fails
    .return();  // returns the actual result

// Mathematical operations with validation
const divide = _tcx(
    ['number', 'number'],
    (a, b) => {
        if (b === 0) throw new Error('Division by zero');
        return a / b;
    },
    { validOutput: 'number' }
);

const result = divide(10, 2).return();  // 5

// API function wrapper
const fetchUser = _tcx(
    ['number'],
    async function(userId) {
        const response = await fetch(`/api/users/${userId}`);
        return await response.json();
    },
    { 
        validOutput: '{id: number, name: string, email: string}',
        error: 'Invalid user data received from API'
    }
);

// Usage with async
const user = await fetchUser(123).fail().return();

addTypeTest()

Register custom type validators

addTypeTest(name, validationFunction)

Parameters:

  • name (string) - Name of the custom type
  • validationFunction (function) - Function that returns boolean for validation

Returns: true if added successfully, error message if name already exists

Examples:

import { addTypeTest, typeCheck } from '@knighttower/type-check';

// Custom validator for even numbers
addTypeTest('even', (value) => {
    return typeof value === 'number' && value % 2 === 0;
});

typeCheck(4, 'even');    // ✅ passes
typeCheck(3, 'even');    // ❌ throws
typeCheck([2, 4, 6], '[even]');  // ✅ all even numbers

// Email validation
addTypeTest('email', (value) => {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    return typeof value === 'string' && emailRegex.test(value);
});

typeCheck('[email protected]', 'email');  // ✅
typeCheck('invalid-email', 'email');     // ❌

// Non-empty string
addTypeTest('nonEmptyString', (value) => {
    return typeof value === 'string' && value.trim().length > 0;
});

// Positive number
addTypeTest('positive', (value) => {
    return typeof value === 'number' && value > 0;
});

// Use in complex validations
typeCheck({
    name: 'John Doe',
    email: '[email protected]',
    age: 25
}, '{name: nonEmptyString, email: email, age: positive}');

// URL validation
addTypeTest('url', (value) => {
    try {
        new URL(value);
        return true;
    } catch {
        return false;
    }
});

// Date string validation
addTypeTest('dateString', (value) => {
    return typeof value === 'string' && !isNaN(Date.parse(value));
});

// Use custom types in arrays and objects
typeCheck(['2023-01-01', '2023-12-31'], '[dateString]');
typeCheck({
    homepage: 'https://example.com',
    created: '2023-01-01'
}, '{homepage: url, created: dateString}');

🔤 Type Patterns


🚀 Usage

import { typeCheck } from '@knighttower/type-check';

typeCheck(123, 'number'); // ✅
typeCheck('hello', 'number'); // ❌ throws

👉 IMPORTANT

The API for the direct typeCheck() function uses the familiar value, type order:

typeCheck(valueToTest, typeExpression);

⚡ Quick Start

typeCheck('hello', 'string'); // ✅
typeCheck([1, 2], '[number]'); // ✅
typeCheck({ x: 1 }, '{x: number}'); // ✅

🧪 Examples

// With optional arguments
typeCheck(null, 'string?'); // true
typeCheck(undefined, 'string?'); // true
typeCheck('str', 'string?'); // true
typeCheck(null, 'string?', options); 
typeCheck(null, 'string?', 'error message'); // throws error with custom message

// Piped
typeCheck(1, 'string | number'); // true
typeCheck('str', 'string | int'); // true

// Array
typeCheck([1], '[number]'); // true
typeCheck([1, 2, 3], '[number]'); // true
typeCheck([1, 3, null], '[number, number, string]'); // Matches the index of the array

// Object
typeCheck({ x: 'string', y: 10 }, '{x: string, y: number}'); // true
typeCheck({ x: 'string', y: 'str' }, '{x: string, y: number}'); // false
typeCheck({ x: 'string', y: 10, z: 10 }, '{x: string, y: number}'); // false
typeCheck({ x: 2, y: 10 }, '{x: string|number, y: number}'); // true

// Object with optional keys
typeCheck({ x: 'string', y: 10 }, '{x: string, y: number, z?: number}'); // true

// Object with specific keys to test all other ignore
typeCheck({ x: 'string', y: 10, z: 20 }, '{x: string, y: number, ...}'); // true

// Object with specific keys to test all test a common test method
typeCheck({ x: 'string', y: 10, z: 20 }, '{x: string, y: number, any: number}'); // true

// Nested arrays or objects
typeCheck([1, { x: 'string', y: 10, z: 20 }, 3], '[number, {any: number, x: string}, number]'); // true

// With callback functions
_typeCheck({ x: 'string', y: 10 }, '{y: number, x: string}', ($this) => {
    console.log('__testLogHere__', $this);
}).log();

//with log function to see the results in the console
_typeCheck({ x: 'string', y: 10 }, '{y: number, x: string}').log();

//with fail function to stop execution if the type is not correct
_typeCheck({ x: 'string', y: 10 }, '{y: number, x: string}').fail();
// Basic
_typeCheck(1, 'number').test(); // true and returns a boolean
_typeCheck('1', 'number').fail().test(); // false and throw exception
_typeCheck('str', 'string').log().test(); // true and logs the test results

🧰 Advanced API

_typeCheck(valueToTest, testExpression, options?)

/**
 * @param {any} valueToTest
 * @param {string} testExpression (see below for patterns)
 * @param {function} callback optional
 * @return {object} typeCheck Object with chainable methods
 * @see testUnit for more examples and test cases
 */
_typeCheck(valueToTest, testExpression, options);

// Methods:
_typeCheck(..).test(); // returns true or false, helpful for if statements or other logic
_typeCheck(..).bool; // same as 'test()', returns true or false, but more direct in the intent
_typeCheck(..).log(); // logs the results, helpful for debugging
_typeCheck(..).fail(); // throws exception if the test fails. Strict validation enforcement
_typeCheck(..).return(); // returns the valueToTest (non chainable with 'test' method)

//Chain methods
_typeCheck(..).log().test();
_typeCheck(..).fail().test();
_typeCheck(..).log().fail().return();

// Options
{
    log: true,
    fail: true,
    callback: function,
    error: string
}

validType(valueToTest, testExpression, options);

Alias function for _typeCheck(valueToTest, testExpression, options); It does not do strict validation, but returns a boolean instead of throwing an exception.

function yourExistingFunction(valueToTest) {
    validType(valueToTest, 'string');
    // your code here
}

_tc(testExpression, __function, options);

  • Wrapper for "typeCheck" (_tc) to implement functions with type checking.
  • Does not validate the "return value" of the function. (use "_tcx" instead).
  • lightweight, fast and easy to implement.
  • Does take options.
  • Does return the 'return value' of the function for each instance.
  • Note: all test expressions are passed as 'array' like because args are 1 or more.
const greet = _tc(['string'], function (name) {
  return `Hello, ${name}`;
});

greet('Alice'); // ✅
greet(123);     // ❌ throws
const logData = _tc(['number', 'boolean'], (id, active) => {
  return `${id}:${active}`;
});

logData(5, true); // ✅
logData('5', true); // ❌ throws
const yourCoolFunction = _tc(['number', 'string'], function (myVar, theOtherVar) {
    // .. your code here
});

yourCoolFunction(44.5, 'hello'); // validates that both are numbers

// Options
{
    log: false, // default false. Same as method log()
    fail: false, // default true. Same as method fail()
    error: string, // custom error message
}

_tcx(testExpression, __function, options);

  • Wrapper for "typeCheck" with 'return X' (_tcx) to implement functions with type checking
  • Validates the "return value" of the function.
  • Offers more options.
  • Has built in features for all its instances.
  • Does take options.
  • slighty slower than "_tc", but more robust for full type checking.
  • Does not return the 'return value' as '_tc', instead it has to be explicitly called with '.return()'.
  • Note: all test expressions are passed as 'array' like because args are 1 or more.
const yourCoolFunction = _tcx(['number', 'string'], function (myVar, theOtherVar) {
    // .. your code here
    return 'hello';
}, {validOutput: 'string'});

yourCoolFunction(44.5, 'hello'); // validates that arg1 is 'number' and arg2 is 'string' and that the return value is a string

// Options
{
    validOutput: 'testExpression', // default null. Same as method log()
    log: false, // default false. Same as method log()
    fail: false, // default true. Same as method fail()
    error: string, // custom error message
}

// Built in features
yourCoolFunction(...).log(); // logs the results, helpful for debugging individual functions
yourCoolFunction(...).fail(); // throws exception if the test fails. Strict validation enforcement
yourCoolFunction(...).return(); // returns the 'return value' (non chainable with 'test' method)
yourCoolFunction(...).test(); // returns true or false, helpful for if statements or other logic
yourCoolFunction(...).fail().return(); // if the test fails, it will throw exception and if passes returns the 'return value'
const getLength = _tcx(['string'], (str) => str.length, {
  validOutput: 'number',
});

getLength('hello').log().return(); // ✅ 5
const sum = _tcx(['number', 'number'], (a, b) => a + b, {
  validOutput: 'number',
});

sum(10, 5).log().fail().return(); // ✅ 15

addTypeTest(name, fn)

Registers a custom type function globally.

addTypeTest('even', (x) => typeof x === 'number' && x % 2 === 0);

typeCheck(2, 'even'); // ✅
typeCheck(3, 'even'); // ❌ throws

typeCheck([2, 4, 6], '[even]'); // ✅
typeCheck({ count: 8 }, '{count: even}'); // ✅
addTypeTest('nonEmptyString', (val) =>
  typeof val === 'string' && val.trim().length > 0
);

typeCheck('hello', 'nonEmptyString'); // ✅
typeCheck('', 'nonEmptyString');      // ❌

🔤 Possible Patterns

Possible type patterns:

// basic string
'type' // only one test
'type | type' // returns to test one or more types
'type?' // is type or null/undefined
'type | type?' // the second type would be type or null/undefined


// basic array
'[type]' // returns test to test all the keys
'[type | type]' // returns test to test all key with one or more
'[[type],[type]]'

// basic object
'{key1: type}'
'{key1: type | type}'
'{key1: type, key2: type}'
'{key1: type, key2?: type}' // if key2 is not present or null/undefined, it will not be tested
'{key1: type, key2: type?}' // if key2 is not set or null/undefined, it will not be tested
'{key1: type | type, key2: type | type}'
'{any: type}' // any key
'{any: type | type}' // any key
'{key1: type, any: type}' // specific key, and all other "any"
'{key1: type | type, ...}' // specific key, and all other no test


// ADVANCE
// array of objects
## 🔤 Type Patterns

TypeCheck JS supports a rich pattern syntax for expressing complex type requirements:

### Basic Types

```javascript
// Single type
'string'    // must be string
'number'    // must be number  
'boolean'   // must be boolean
'null'      // must be null
'undefined' // must be undefined
'array'     // must be array
'object'    // must be object
'function'  // must be function

// Optional types (allows null/undefined)
'string?'   // string, null, or undefined
'number?'   // number, null, or undefined

// Union types (multiple allowed types)
'string|number'           // string OR number
'boolean|string|number'   // any of the three types
'array|object'            // array OR object

// Combined optional and union
'string|number?'          // string, number, null, or undefined

Array Patterns

// Homogeneous arrays (all elements same type)
'[string]'     // array of strings
'[number]'     // array of numbers
'[boolean]'    // array of booleans

// Heterogeneous arrays (specific positions)
'[string, number]'              // first element string, second number
'[string, number, boolean]'     // three elements with specific types
'[object, array, string]'       // mixed types at specific positions

// Union types in arrays
'[string|number]'               // array where all elements are string OR number
'[string, number|boolean]'      // first string, second number OR boolean

// Nested arrays
'[[string]]'                    // array of string arrays
'[string, [number]]'            // first string, second is number array
'[[string, number]]'            // array containing [string, number] pairs

// Optional elements in arrays
'[string, number?]'             // second element optional

Object Patterns

// Basic object structure
'{name: string}'                          // object with name property (string)
'{name: string, age: number}'             // object with name and age properties
'{id: number, active: boolean}'           // id (number) and active (boolean)

// Optional properties
'{name: string, age?: number}'            // age property is optional
'{id: number, email?: string}'            // email property is optional

// Union types in properties
'{status: string|number}'                 // status can be string OR number
'{data: string|array|object}'             // data can be multiple types

// Any key validation (all properties same type)
'{any: string}'                           // all property values must be strings
'{any: number}'                           // all property values must be numbers
'{any: string|number}'                    // all values string OR number

// Mixed specific and any
'{id: number, any: string}'               // id must be number, others string
'{name: string, age: number, any: boolean}' // specific props + others boolean

// Ignore extra properties
'{name: string, ...}'                     // name required, ignore other props
'{id: number, email: string, ...}'        // specified props required, others ignored

// Nested objects
'{user: {name: string, age: number}}'     // nested object structure
'{config: {theme: string, debug: boolean}}' // nested configuration object

// Complex nested structures
'{users: [{id: number, name: string}]}'   // array of user objects
'{response: {data: [object], meta: {total: number}}}' // complex API response

Advanced Patterns

// Enums (specific values only)
'enum=red/green/blue'                     // only these three values allowed
'enum=small/medium/large'                 // size enum
'enum=admin/user/guest'                   // role enum

// Enums with other types
'string|enum=active/inactive'             // string OR specific enum values
'enum=1/2/3|string'                       // enum values OR any string

// Complex array patterns
'[{name: string, tags: [string]}]'        // array of objects with string arrays
'[string, {count: number}, [boolean]]'    // mixed: string, object, boolean array

// Real-world examples
'{id: number, user: {name: string, email: string}, items: [{id: number, quantity: number}]}'

// API response patterns
'{data: [object], pagination: {page: number, total: number}, meta: {timestamp: string}}'

// Form validation patterns
'{email: string, password: string, confirmPassword?: string, terms: boolean}'

// Configuration object patterns
'{api: {baseUrl: string, timeout: number?}, features: {darkMode: boolean, notifications: boolean}}'

Pattern Examples with Use Cases

// User profile validation
const userPattern = `{
    id: number,
    email: string,
    profile: {
        firstName: string,
        lastName: string,
        avatar?: string
    },
    preferences: {
        theme: enum=light/dark,
        notifications: boolean
    },
    roles: [enum=admin/user/moderator]
}`;

// E-commerce order
const orderPattern = `{
    orderId: string,
    customer: {id: number, email: string},
    items: [{
        productId: number,
        name: string,
        price: number,
        quantity: number
    }],
    shipping: {
        address: string,
        method: enum=standard/express/overnight
    },
    total: number
}`;

// API response with pagination
const apiResponsePattern = `{
    data: [object],
    pagination: {
        page: number,
        limit: number,
        total: number,
        hasNext: boolean
    },
    meta?: {
        timestamp: string,
        version: string
    }
}`;

📝 Comprehensive Examples

Form Validation

import { validType, typeCheck } from '@knighttower/type-check';

function validateRegistrationForm(formData) {
    const errors = [];
    
    // Basic field validation
    if (!validType(formData.email, 'string')) {
        errors.push('Email is required');
    }
    
    if (!validType(formData.password, 'string')) {
        errors.push('Password is required');
    }
    
    // Complex object validation
    if (!validType(formData, '{email: string, password: string, age?: number}')) {
        errors.push('Invalid form structure');
    }
    
    // Custom validation with typeCheck for strict enforcement
    try {
        typeCheck(formData.preferences, '{newsletter: boolean, theme: enum=light/dark}');
    } catch (error) {
        errors.push('Invalid preferences');
    }
    
    return errors;
}

// Usage
const formData = {
    email: '[email protected]',
    password: 'securePassword',
    age: 25,
    preferences: {
        newsletter: true,
        theme: 'dark'
    }
};

const errors = validateRegistrationForm(formData);

API Data Validation

import { _typeCheck, addTypeTest } from '@knighttower/type-check';

// Custom validation for ISO date strings
addTypeTest('isoDate', (value) => {
    return typeof value === 'string' && !isNaN(Date.parse(value));
});

// API endpoint with validation
async function fetchUserOrders(userId) {
    // Validate input
    typeCheck(userId, 'number');
    
    const response = await fetch(`/api/users/${userId}/orders`);
    const data = await response.json();
    
    // Validate API response structure
    const isValid = _typeCheck(data, `{
        orders: [{
            id: number,
            status: enum=pending/processing/shipped/delivered,
            items: [{name: string, quantity: number, price: number}],
            createdAt: isoDate,
            total: number
        }],
        pagination: {page: number, totalPages: number}
    }`).test();
    
    if (!isValid) {
        throw new Error('Invalid API response format');
    }
    
    return data;
}

Function Parameter Validation

import { _tc, _tcx } from '@knighttower/type-check';

// Database query function with validation
const findUsers = _tc(
    ['{filters?: {name?: string, age?: number, active?: boolean}, limit?: number}'],
    function(options = {}) {
        const { filters = {}, limit = 10 } = options;
        
        // Build and execute query
        console.log('Searching users with filters:', filters);
        return mockDatabaseQuery(filters, limit);
    }
);

// Math function with input and output validation
const calculateCompoundInterest = _tcx(
    ['number', 'number', 'number', 'number'],
    function(principal, rate, time, compound) {
        return principal * Math.pow((1 + rate / compound), compound * time);
    },
    { validOutput: 'number' }
);

// Usage
const users = findUsers({
    filters: { active: true, age: 25 },
    limit: 5
});

const investment = calculateCompoundInterest(1000, 0.05, 10, 12).return();

Configuration Validation

import { typeCheck, addTypeTest } from '@knighttower/type-check';

// Custom port number validation
addTypeTest('port', (value) => {
    return typeof value === 'number' && value >= 1 && value <= 65535;
});

// Application configuration
const configPattern = `{
    server: {
        host: string,
        port: port,
        ssl: boolean
    },
    database: {
        url: string,
        pool: {min: number, max: number}
    },
    features: {
        auth: boolean,
        logging: enum=debug/info/warn/error,
        rateLimit?: {
            windowMs: number,
            max: number
        }
    }
}`;

function validateConfig(config) {
    try {
        typeCheck(config, configPattern);
        console.log('Configuration is valid');
        return true;
    } catch (error) {
        console.error('Configuration error:', error.message);
        return false;
    }
}

// Usage
const appConfig = {
    server: {
        host: 'localhost',
        port: 3000,
        ssl: false
    },
    database: {
        url: 'postgresql://localhost:5432/myapp',
        pool: { min: 2, max: 10 }
    },
    features: {
        auth: true,
        logging: 'info',
        rateLimit: {
            windowMs: 900000,
            max: 100
        }
    }
};

validateConfig(appConfig);

Real-time Data Validation

import { _typeCheck } from '@knighttower/type-check';

// WebSocket message validation
function handleWebSocketMessage(message) {
    // Log validation details in development
    const validation = _typeCheck(message, `{
        type: enum=user_joined/user_left/message/typing,
        payload: {
            userId: number,
            username: string,
            content?: string,
            timestamp: number
        }
    }`).log();
    
    if (!validation.test()) {
        console.warn('Invalid message format received');
        return;
    }
    
    // Process valid message
    const { type, payload } = message;
    switch (type) {
        case 'message':
            displayMessage(payload);
            break;
        case 'user_joined':
            showUserJoined(payload);
            break;
        // ... other cases
    }
}

// Event handler validation
const handleUserAction = _tc(
    ['{action: enum=click/hover/focus, target: string, data?: object}'],
    function(event) {
        console.log(`User ${event.action} on ${event.target}`);
        if (event.data) {
            console.log('Additional data:', event.data);
        }
    }
);

⚡ Performance

'[{key1: type | type}]' // returns test to test all key with one or more '[{key1: type, key2: type}]' // returns '[{key1: type, key2: type}, {key1: type, key2: type}]' '[{key1: type | type, key2: type | type}, {key1: type | type, key2: type | type}]' '[{key1: type, any: type}]'


## ⚡ Performance

TypeCheck JS is designed for production use with minimal performance overhead:

### Benchmarks

- **Lightweight**: ~6k gzipped, minimal bundle impact
- **Fast Execution**: Micro-optimized for runtime operations
- **Caching**: Built-in caching for type patterns and validations
- **Memory Efficient**: Reuses validation functions and patterns

### Performance Comparison

```javascript
// Benchmark example (1000 iterations)
import { _tc, _tcx, typeCheck } from '@knighttower/type-check';

// _tc: ~3ms for 1000 function calls with validation
const fastFunction = _tc(['[number]'], (arr) => arr.reduce((a, b) => a + b, 0));

// _tcx: ~4ms for 1000 function calls with input/output validation  
const robustFunction = _tcx(['[number]'], (arr) => arr.reduce((a, b) => a + b, 0), {
    validOutput: 'number'
});

// Direct typeCheck: ~2ms for 1000 direct validations
const numbers = [1, 2, 3, 4, 5];
for (let i = 0; i < 1000; i++) {
    typeCheck(numbers, '[number]');
}

Optimization Tips

  1. Reuse wrapped functions: Create _tc and _tcx wrapped functions once, use many times
  2. Use validType() for boolean checks: Faster than _typeCheck().test()
  3. Cache complex patterns: The library automatically caches, but avoid recreating patterns
  4. Prefer simpler patterns: 'string' is faster than 'string|number|boolean'

🧪 Tests

Comprehensive test coverage ensures reliability:

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Run performance benchmarks  
npm run benchmark

Test Files

  • tests/TypeCheck.test.js - Core functionality tests
  • tests/TestBuilder.Unit.test.js - Pattern parsing tests
  • tests/BuildExports.unit.test.js - Export validation tests
  • type-patterns.txt - Extended pattern examples

Example Test Cases

// Basic type validation
expect(validType(123, 'number')).toBe(true);
expect(validType('hello', 'number')).toBe(false);

// Complex object validation
expect(validType({
    user: { name: 'John', age: 30 },
    items: [{ id: 1, name: 'Item' }]
}, '{user: {name: string, age: number}, items: [{id: number, name: string}]}')).toBe(true);

// Custom type tests
addTypeTest('even', x => typeof x === 'number' && x % 2 === 0);
expect(validType(4, 'even')).toBe(true);
expect(validType(3, 'even')).toBe(false);

// Function wrapper tests
const fn = _tc(['string'], (str) => str.toUpperCase());
expect(() => fn('hello')).not.toThrow();
expect(() => fn(123)).toThrow();

🔧 Advanced Usage

TypeScript Integration

TypeCheck JS works alongside TypeScript for runtime validation:

import { typeCheck, validType } from '@knighttower/type-check';

interface User {
    id: number;
    name: string;
    email: string;
}

function processUser(data: unknown): User {
    // Runtime validation
    typeCheck(data, '{id: number, name: string, email: string}');
    
    // Now TypeScript knows data is valid
    return data as User;
}

// API response validation
async function fetchUser(id: number): Promise<User> {
    const response = await fetch(`/api/users/${id}`);
    const data = await response.json();
    
    if (!validType(data, '{id: number, name: string, email: string}')) {
        throw new Error('Invalid user data from API');
    }
    
    return data;
}

Error Handling

import { typeCheck, _typeCheck } from '@knighttower/type-check';

// Custom error messages
try {
    typeCheck(invalidData, 'string', { 
        error: 'User input must be a valid string' 
    });
} catch (error) {
    console.error('Validation failed:', error.message);
}

// Graceful validation
function safeValidation(data, pattern) {
    const result = _typeCheck(data, pattern);
    
    if (!result.test()) {
        console.warn('Data validation failed for pattern:', pattern);
        return null;
    }
    
    return result.return();
}

// Multiple validation attempts
function validateWithFallback(data) {
    const patterns = [
        '{id: number, name: string}',
        '{id: string, name: string}',
        '{name: string}'
    ];
    
    for (const pattern of patterns) {
        if (validType(data, pattern)) {
            console.log('Matched pattern:', pattern);
            return data;
        }
    }
    
    throw new Error('Data does not match any expected pattern');
}

Custom Validation Library

import { addTypeTest, typeCheck } from '@knighttower/type-check';

// Build a custom validation library
class CustomValidators {
    static init() {
        // Email validation
        addTypeTest('email', (value) => {
            const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
            return typeof value === 'string' && emailRegex.test(value);
        });
        
        // Phone number validation
        addTypeTest('phone', (value) => {
            const phoneRegex = /^\+?[\d\s\-\(\)]+$/;
            return typeof value === 'string' && phoneRegex.test(value);
        });
        
        // URL validation
        addTypeTest('url', (value) => {
            try {
                new URL(value);
                return true;
            } catch {
                return false;
            }
        });
        
        // Credit card validation (basic)
        addTypeTest('creditCard', (value) => {
            const ccRegex = /^\d{4}\s?\d{4}\s?\d{4}\s?\d{4}$/;
            return typeof value === 'string' && ccRegex.test(value.replace(/\s/g, ''));
        });
        
        // Strong password validation
        addTypeTest('strongPassword', (value) => {
            const strongRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/;
            return typeof value === 'string' && strongRegex.test(value);
        });
    }
}

// Initialize custom validators
CustomValidators.init();

// Use custom validators
const userRegistration = {
    email: '[email protected]',
    phone: '+1-555-123-4567',
    website: 'https://example.com',
    password: 'MyStr0ng!Pass'
};

typeCheck(userRegistration, `{
    email: email,
    phone: phone,
    website: url,
    password: strongPassword
}`);

🤝 Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature-name
  3. Make your changes with tests
  4. Run the test suite: npm test
  5. Submit a pull request

Development Setup

git clone https://github.com/knighttower/typeCheckJs.git
cd typeCheckJs
npm install
npm test

📄 License

MIT License - see LICENSE file for details.


🔗 Related Projects

Check out other tools in the Knight Tower ecosystem:


Check out other cool stuff at https://knighttower.io and help support open source projects.

🙌 Sponsored By

Squarefox