@leglaine/node-types
v1.0.0
Published
A highly composable runtime type checking library for JavaScript and Node.js.
Maintainers
Readme
@leglaine/node-types
A lightweight, flexible type checking library for Node.js. Supports primitives, collections, nested checks, custom checks, and both high-performance and chainable APIs.
Table of Contents
Features
- Type checks for primitives (
string,number,boolean,null,undefined) - Type checks for boxed values (
new String,new Number,new Boolean) - Type checks for numeric values (
integer,finite,positive,negative,even,odd) - Type checks for special objects (
symbol,date,regexp) - Type checks for empty collections or objects
- Collection checks (
array,object,set,map) with single-type, multi-type, and positional support - Custom type checks via
registerCheck() - Negation with
.not - Chainable API via
is() - Auto-unwrapping helpers (
isX()) and high-performance raw checks (isXFast()) - Optional prototype extensions for syntactic sugar
Quick Start
npm install @leglaine/node-typesconst { is } = require("@leglaine/node-types");
if (is(10).number) {
console.log("10 is a number");
}Guide
Basic Typechecking
// Primitives
is(5).number; // true
is("hello").string; // true
is(false).boolean; // true
is(null).null; // true
is(undefined).undefined; // true
is(Symbol("foo")).symbol; // true
// Boxed Values
is(new Number(5)).number; // true
is(new String("abc")).string; // true
is(new Boolean(false)).boolean; // true
// Numerics
is(10.5).integer; // false
is(Infinity).finite; // false
is(4).even; // true
is(3).odd; // true
is(-5).negative; // true
is(10).positive; // true
// Empty
is({}).empty; // true
// Special Objects
is(new Date()).date; // true
is(new RegExp("a")).regexp; // trueNegation
is("hello").not.null; // true
is(345).not.undefined; // true
is([1, 2, 3]).not.empty; // trueCollections
Arrays
// Untyped
is([1, "a", true]).array(); // true
// Single-type
is([1, 2, 3]).array("number"); // true
is([1, "2", 3]).array("number"); // false
// Multi-type (positional)
is([1, "a"]).array("number", "string"); // true
is([1, "a", true]).array("number", "string"); // false
// Nested
is([
[1, 2],
[3, 4],
]).array(array("number")); // trueObjects
is({ a: 1, b: 2 }).object(); // true
is({ a: 1, b: 2 }).object("number"); // all values are numbers: true
is({ a: 1, b: "x" }).object("number", "string"); // multiple allowed types: true
// Nested
is({ a: [1, 2], b: [3, 4] }).object(array("number")); // true
is({ a: { x: 1 }, b: { y: 2 } }).object(object("number")); // trueMaps
const m = new Map([
["a", 1],
["b", "x"],
]);
is(m).map("number", "string"); // true
// Nested
const nestedMap = new Map([
["a", new Map([["x", 1]])],
["b", new Map([["y", 2]])],
]);
is(nestedMap).map(map("number")); // trueSets
is(new Set([1, 2])).set("number"); // true
is(new Set([1, "x"])).set("number", "string"); // true
is(new Set([1, {}])).set("number", "string"); // false
// Nested
is(new Set([new Set([1, 2]), new Set([3, 4])])).set(set("number")); // trueCustom Checks
const { registerCheck, is } = require("@leglaine/node-types");
registerCheck("evenOrGreaterThan10", (n) => n % 2 === 0 || n > 10);
is(12).evenOrGreaterThan10; // true
is(7).evenOrGreaterThan10; // falseAuto-Unwrap & High-Performance APIs
See performance notes for more information.
const { isNumber, isNumberFast } = require("@leglaine/node-types");
isNumber(new Number(5)); // true (auto-unwrap)
isNumberFast(new Number(5)); // false, not unwrapped
isNumberFast(5); // truePrototypes
Optionally extend built-in prototypes for syntactic sugar.
⚠️ Warning: Use with caution. Pollutes global prototypes.
useIsPrototypes();
"hello".is.string; // true
(42).is.number; // truePerformance Notes
- is() proxies introduce minor overhead for composable checks.
- isX() functions skip proxies, but include auto-unwrapping.
- isXFast() functions skip proxies and auto-unwrapping for maximum performance.
- Prefer isXFast for tight loops or high-volume checks.
Benchmarks
| function | ops/sec (approx.) |
| ---------------------------- | ----------------- |
| is().number (proxy) | ~ 1 Million |
| isNumber() (no proxy) | ~ 10 Million |
| isNumberFast() (no unwrap) | ~ 75 Million |
| _.isNumber() (lodash) | ~ 3 Million |
License
MIT © 2025 Lexi Wright
See LICENSE for more information.
