Function argument validation for humans with expressive, chainable API
npx @tessl/cli install tessl/npm-ow@2.0.0Ow is a TypeScript function argument validation library for humans that provides expressive, chainable APIs for validating JavaScript and TypeScript values. It offers comprehensive validation for all JavaScript types including primitives, built-in types, typed arrays, and complex structured data with automatic label inference and TypeScript type guards.
npm install owimport ow from 'ow';For CommonJS:
const ow = require('ow');Development-only imports (automatically shimmed in production):
import ow from 'ow/dev-only';Type utilities:
import ow, { Infer, ArgumentError } from 'ow';import ow from 'ow';
// Basic validation with automatic label inference
const validateUser = (input) => {
ow(input, ow.object.exactShape({
name: ow.string.minLength(2),
age: ow.number.integer.positive,
email: ow.optional.string.matches(/^.+@.+\..+$/)
}));
};
// With custom label
ow('hello', 'greeting', ow.string.minLength(10));
// => ArgumentError: Expected string `greeting` to have a minimum length of `10`, got `hello`
// Boolean validation instead of throwing
if (ow.isValid(42, ow.string)) {
console.log('Never runs');
}
// Create reusable validators
const checkPassword = ow.create('password', ow.string.minLength(8));
checkPassword('weak');
// => ArgumentError: Expected string `password` to have a minimum length of `8`, got `weak`Ow is built around several key components:
ow() for assertions, ow.isValid() for boolean checks, ow.create() for reusable validators.not, .is(), .validate(), .message()) available on all predicatesMain validation functions and utilities for creating validators and checking values.
/** Test if value matches predicate, throws ArgumentError on failure */
function ow<T>(value: unknown, predicate: BasePredicate<T>): asserts value is T;
/** Test with custom label for error messages */
function ow<T>(value: unknown, label: string, predicate: BasePredicate<T>): asserts value is T;
/** Returns boolean instead of throwing, provides type guards */
function isValid<T>(value: unknown, predicate: BasePredicate<T>): value is T;
/** Create reusable validator function */
function create<T>(predicate: BasePredicate<T>): ReusableValidator<T>;
function create<T>(label: string, predicate: BasePredicate<T>): ReusableValidator<T>;
/** Returns predicate that passes if any of the provided predicates match */
function any<T1>(p1: BasePredicate<T1>): AnyPredicate<T1>;
function any<T1, T2>(p1: BasePredicate<T1>, p2: BasePredicate<T2>): AnyPredicate<T1 | T2>;
// ... supports up to 10 predicates
type ReusableValidator<T> = (value: unknown, label?: string) => void;Validation for JavaScript primitive types including strings, numbers, booleans, and symbols with extensive chainable methods.
const string: StringPredicate;
const number: NumberPredicate;
const boolean: BooleanPredicate;
const bigint: BigIntPredicate;
const symbol: Predicate<symbol>;
const undefined: Predicate<undefined>;
const null: Predicate<null>;
const nullOrUndefined: Predicate<null | undefined>;
const nan: Predicate<number>;Advanced validation for objects and arrays including shape validation, property checking, and element type validation.
const object: ObjectPredicate;
const array: ArrayPredicate;
interface ObjectPredicate {
exactShape<S>(shape: S): ObjectPredicate;
partialShape<S>(shape: S): ObjectPredicate;
hasKeys(...keys: string[]): ObjectPredicate;
// ... more methods
}
interface ArrayPredicate {
ofType<U>(predicate: BasePredicate<U>): ArrayPredicate;
length(length: number): ArrayPredicate;
includes(...searchElements: T[]): ArrayPredicate;
// ... more methods
}Validation for JavaScript built-in types like Date, Error, RegExp, Promise, Function, and Buffer.
const date: DatePredicate;
const error: ErrorPredicate;
const regExp: Predicate<RegExp>;
const promise: Predicate<Promise<unknown>>;
const function: Predicate<Function>;
const buffer: Predicate<Buffer>;Validation for JavaScript collection types including Map, Set, WeakMap, and WeakSet with size and content validation.
const map: MapPredicate;
const set: SetPredicate;
const weakMap: WeakMapPredicate;
const weakSet: WeakSetPredicate;
const iterable: Predicate<Iterable<unknown>>;Comprehensive validation for all typed array types with length and byte length validation methods.
const typedArray: TypedArrayPredicate<TypedArray>;
const int8Array: TypedArrayPredicate<Int8Array>;
const uint8Array: TypedArrayPredicate<Uint8Array>;
const uint8ClampedArray: TypedArrayPredicate<Uint8ClampedArray>;
const int16Array: TypedArrayPredicate<Int16Array>;
const uint16Array: TypedArrayPredicate<Uint16Array>;
const int32Array: TypedArrayPredicate<Int32Array>;
const uint32Array: TypedArrayPredicate<Uint32Array>;
const float32Array: TypedArrayPredicate<Float32Array>;
const float64Array: TypedArrayPredicate<Float64Array>;
const arrayBuffer: ArrayBufferPredicate<ArrayBuffer>;
const sharedArrayBuffer: ArrayBufferPredicate<SharedArrayBuffer>;
const dataView: DataViewPredicate;Optional predicates, custom validation, error handling, and TypeScript type utilities.
/** Make any predicate optional (allows undefined) */
const optional: {
string: StringPredicate & BasePredicate<string | undefined>;
number: NumberPredicate & BasePredicate<number | undefined>;
// ... all other predicates as optional
};
/** Extract TypeScript type from predicate */
type Infer<P> = P extends BasePredicate<infer T> ? T : never;
/** Error thrown when validation fails */
class ArgumentError extends Error {
name: 'ArgumentError';
}
/** Base interface for all predicates */
interface BasePredicate<T> {
not: BasePredicate<T>;
is(validator: (value: T) => boolean | string): BasePredicate<T>;
validate(customValidator: CustomValidator<T>): BasePredicate<T>;
message(newMessage: string | MessageBuilder<T>): BasePredicate<T>;
}/** Extract TypeScript type from predicate */
type Infer<P> = P extends BasePredicate<infer T> ? T : never;
/** Base interface for all predicates */
interface BasePredicate<T> {
// Base predicate methods available on all predicates
}
/** Reusable validator function created with ow.create() */
type ReusableValidator<T> = (value: unknown, label?: string) => void;
/** Type assertion version of reusable validator */
type AssertingValidator<T> = (value: unknown, label?: string) => asserts value is T;
/** Error thrown when validation fails */
class ArgumentError extends Error {
name: 'ArgumentError';
}import ow, { Infer } from 'ow';
// Extract types from predicates
const userPredicate = ow.object.exactShape({
name: ow.string,
age: ow.number.integer.positive,
email: ow.optional.string
});
type User = Infer<typeof userPredicate>;
// Result: { name: string; age: number; email?: string | undefined }
// Type guards in action
function processValue(input: unknown) {
ow(input, ow.string.minLength(5));
// TypeScript now knows input is string with length >= 5
return input.toUpperCase();
}