Runtime validation for static types
npx @tessl/cli install tessl/npm-runtypes@7.0.0Runtypes is a comprehensive TypeScript library that provides runtime type validation for safely bringing untyped data into strongly-typed applications. It offers composable type validators for primitives, literals, arrays, tuples, objects, unions, intersections and more, enabling developers to validate data structures at runtime while maintaining full static type safety.
npm install runtypesimport {
String, Number, Boolean, Array, Object, Union, Literal,
Never, Nullish, InstanceOf, ValidationError,
Contract, AsyncContract, Constraint, Brand, Parser,
type Static, type Parsed, type Failcode
} from "runtypes";For CommonJS:
const {
String, Number, Boolean, Array, Object, Union, Literal,
Never, Nullish, InstanceOf, ValidationError,
Contract, AsyncContract, Constraint, Brand, Parser
} = require("runtypes");import { String, Number, Object, Array, Union, Literal } from "runtypes";
// Define a user schema
const User = Object({
id: Number,
name: String,
email: String,
age: Number.optional(),
status: Union(Literal("active"), Literal("inactive"))
});
// Extract TypeScript types
type UserType = Static<typeof User>;
// Validate data at runtime
const userData = {
id: 1,
name: "Alice",
email: "alice@example.com",
status: "active"
};
try {
const validUser = User.check(userData);
console.log("Valid user:", validUser);
} catch (error) {
console.error("Validation failed:", error.message);
}
// Use guard for type narrowing
if (User.guard(userData)) {
// userData is now typed as UserType
console.log(userData.name); // TypeScript knows this is a string
}Runtypes is built around several core concepts:
check, guard, assert, parse, inspect)Static<T> and Parsed<T> utilitiesCore type validators for JavaScript primitive values and special types.
const String: Runtype<string>;
const Number: Runtype<number>;
const Boolean: Runtype<boolean>;
const BigInt: Runtype<bigint>;
const Symbol: Runtype<symbol>;
const Null: Runtype<null>;
const Undefined: Runtype<undefined>;
const Unknown: Runtype<unknown>;
const Never: Runtype<never>;
const Nullish: Union<[typeof Null, typeof Undefined]>;
const Void: Runtype<unknown>; // deprecated alias for UnknownValidates exact literal values using SameValueZero equality.
function Literal<T extends LiteralValue>(value: T): Runtype<T>;
type LiteralValue = undefined | null | boolean | number | bigint | string;Validates that values are instances of specific classes.
function InstanceOf<V>(ctor: Constructor<V>): Runtype<V>;
type Constructor<V> = { new (...args: never[]): V };Complex data structure validators for arrays, objects, and tuples.
function Array<R extends Runtype.Core>(element: R): Array<R>;
function Object<O extends Object.Fields>(fields: O): Object<O>;
function Tuple<R extends readonly (Runtype.Core | Spread)[]>(...components: R): Tuple<R>;
function Record<K extends PropertyKey, V>(key: Runtype<K>, value: Runtype<V>): Record<K, V>;Combines multiple runtypes for flexible validation.
function Union<R extends readonly Runtype.Core[]>(...alternatives: R): Union<R>;
function Intersect<R extends readonly Runtype.Core[]>(...intersectees: R): Intersect<R>;Enables recursive type definitions by deferring runtype creation.
function Lazy<R extends Runtype.Core>(fn: () => R): Lazy<R>;Validates template literal strings with typed interpolation.
function Template<A extends readonly [string, ...string[]], B extends readonly Runtype.Core<LiteralValue>[]>(
strings: A,
...runtypes: B
): Template<A, B>;
type LiteralValue = undefined | null | boolean | number | bigint | string;Add custom validation logic and data transformation.
function Constraint<T, U extends T>(
underlying: Runtype<T>,
constraint: (x: T) => asserts x is U
): Runtype<U>;
function Brand<B extends string, T>(brand: B, entity: Runtype<T>): Runtype<T & Brand<B>>;
function Parser<T, U>(underlying: Runtype<T>, parser: (value: T) => U): Runtype<U>;Constraints and Transformations
Runtime validation for function arguments and return values.
function Contract<O extends ContractOptions>(options: O): ContractType<O>;
function AsyncContract<O extends AsyncContractOptions>(options: O): AsyncContractType<O>;
interface ContractOptions {
receives?: Runtype<readonly unknown[]>;
returns?: Runtype;
}Structured results for validation operations with detailed error information.
type Result<T> = Success<T> | Failure;
interface Success<T> {
success: true;
value: T;
}
interface Failure {
success: false;
code: Failcode;
message: string;
expected: Runtype;
received: unknown;
details?: Record<PropertyKey, Failure>;
detail?: Failure;
thrown?: unknown;
}Every runtype provides these essential validation methods.
interface Runtype<T, X = T> {
check<U>(x: U): T & U;
guard<U>(x: U): x is T & U;
assert<U>(x: U): asserts x is T & U;
parse<U>(x: U): X;
inspect<U>(x: U, options?: { parse?: boolean }): Result<T | X>;
}Methods available on every runtype for composition, constraints, and transformations.
interface Runtype<T, X = T> {
// Composition methods
or<R extends Runtype.Core>(other: R): Union<[this, R]>;
and<R extends Runtype.Core>(other: R): Intersect<[this, R]>;
// Optional and nullable shortcuts
optional(): Optional<this, never>;
default<V = never>(value: V): Optional<this, V>;
nullable(): Union<[this, Literal<null>]>;
undefinedable(): Union<[this, Literal<undefined>]>;
nullishable(): Union<[this, Literal<null>, Literal<undefined>]>;
// Constraint methods
withConstraint<Y extends T>(constraint: (x: T) => boolean | string): Constraint<this, Y>;
withGuard<Y extends T>(guard: (x: T) => x is Y): Constraint<this, Y>;
withAssertion<Y extends T>(assert: (x: T) => asserts x is Y): Constraint<this, Y>;
// Branding and parsing
withBrand<B extends string>(brand: B): Brand<B, this>;
withParser<Y>(parser: (value: X) => Y): Parser<this, Y>;
// Extension
with<P extends object>(extension: P | ((self: this) => P)): this & P;
// Utilities
clone(): this;
conform<V, Y = V>(this: Conform<V, Y>): Conform<V, Y> & this;
}
// Static methods
interface RuntypeStatic {
isRuntype(x: unknown): x is Runtype.Interfaces;
assertIsRuntype(x: unknown): asserts x is Runtype.Interfaces;
}Pattern matching and other utility functions.
function match<C extends readonly Case[]>(...cases: C): Matcher<C>;
function when<T, U>(runtype: Runtype<T>, transformer: (value: T) => U): Case<T, U>;type Static<R extends Runtype> = /* inferred static type */;
type Parsed<R extends Runtype> = /* inferred parsed type */;
class ValidationError extends Error {
name: "ValidationError";
message: string;
failure: Failure;
constructor(failure: Failure);
static isValidationError(value: unknown): value is ValidationError;
static [Symbol.hasInstance](value: unknown): value is ValidationError;
}
type Failcode =
| "TYPE_INCORRECT"
| "VALUE_INCORRECT"
| "KEY_INCORRECT"
| "CONTENT_INCORRECT"
| "ARGUMENTS_INCORRECT"
| "RETURN_INCORRECT"
| "RESOLVE_INCORRECT"
| "CONSTRAINT_FAILED"
| "PROPERTY_MISSING"
| "PROPERTY_PRESENT"
| "NOTHING_EXPECTED"
| "PARSING_FAILED"
| "INSTANCEOF_FAILED";