typeforce - Runtime Type Checking

1.18.0 · active · verified Sun Apr 19

Typeforce is a JavaScript library designed for biased runtime type checking, offering a comprehensive suite of utilities to enforce data structures and primitive types. As of version 1.18.0, it provides a flexible API for defining complex type schemas, including support for arrays, recursive objects, optional properties (`?`), sum types (`anyOf`), and intersection types (`allOf`). A notable feature is its extensibility through custom type functions, allowing developers to define domain-specific validations. It differentiates itself by offering specialized modules for non-throwing error handling (`typeforce/nothrow`) and asynchronous validation (`typeforce/async`), catering to different error management strategies. While a specific release cadence isn't detailed, its versioning suggests ongoing maintenance and feature development, making it a robust choice for projects requiring strict data validation without relying on static type systems.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates basic, recursive, custom, and strict type checking, along with the no-throw variant and performance tips like precompilation.

var typeforce = require('typeforce');
var typeforceNoThrow = require('typeforce/nothrow');

// Define some data
var user = { id: 123, name: 'Alice' };
var product = { id: 456, price: 10.99 };
var inventory = [user, product];
var configTuple = ['development', 8080];

// Basic type checking for primitives
typeforce('Array', inventory); // OK
typeforce('Number', 123);      // OK

// Array of a specific type (e.g., objects with an ID and a string name)
typeforce(typeforce.arrayOf({ id: 'Number', name: 'String' }), [user]);

// Recursive type templating for objects with optional properties
typeforce({ id: 'Number', name: '?String', price: '?Number' }, product);

// Sum types (anyOf) and intersection types (allOf)
typeforce(typeforce.anyOf('String', 'Number'), 'foobar'); // 'foobar' is String
typeforce(typeforce.allOf({ x: typeforce.Number }, { y: typeforce.String }), { x: 1, y: '2' }); // Both properties must match

// Custom type definition (e.g., a specific length string)
function HexString32(value) {
  return typeforce.String(value) && /^[0-9a-fA-F]{32}$/.test(value);
}
typeforce(HexString32, 'a0b1c2d3e4f5a0b1c2d3e4f5a0b1c2d3'); // OK!

// Using the non-throwing version for graceful error handling
var potentiallyBadValue = 'this is not a number';
if (!typeforceNoThrow(typeforceNoThrow.Number, potentiallyBadValue)) {
  console.log(`Error caught by no-throw: ${typeforceNoThrow.error.message}`);
}

// Protip: use precompiled types for performance on repeated checks
var compiledSchema = typeforce.compile({ 
  id: typeforce.Number,
  timestamp: typeforce.Number
});
compiledSchema({ id: 1, timestamp: Date.now() }); // Fast check!

// Protip: enforce strictness to disallow extra properties
typeforce({ a: 'Number' }, { a: 1 }, true); // OK
try {
  typeforce({ a: 'Number' }, { a: 1, b: 2 }, true); // This will throw an error
} catch (e) {
  console.log(`Strict check error: ${e.message}`);
}

view raw JSON →