creates the types mapping type-->function
Validators that convert before validating.
Query strings, form data and environment variables arrive as strings, so
without these every HTTP handler rewrites the conversion by hand — which
is exactly where the mistakes are made. Each one rejects what it cannot
convert rather than inventing a value, which is the difference between
these and the bare Number() / Boolean() they replace:
| Input | Number() / Boolean() |
typer.coerce.* |
|---|---|---|
'' |
0 |
rejected |
' ' |
0 |
rejected |
null |
0 |
rejected |
[] |
0 |
rejected |
'abc' |
NaN |
rejected |
'false' |
true |
false |
'0' |
true |
false |
In a schema slot the converted value replaces the original, so the
object that comes out of parse holds the numbers and dates, not the
strings that arrived.
The standalone validators, pre-bound to this instance.
The schema API invites passing validators around as values, but
{ id: typer.isPositiveInteger } loses this and fails with an opaque
"Cannot read properties of undefined" — even for input that is valid.
These are bound, so they can be passed, destructured and stored freely.
Built on first access and cached. Binding all of them eagerly onto the instance was measured to slow every other method down several-fold, by pushing the object out of V8's fast property mode — hence the single lazily-populated slot.
Validates and returns an array
The expected element type
The value to validate
The validated array
Validates and returns an object
The expected object type
The value to validate
The validated object
Recursively validates an object against a nested schema.
Shares the closure compiler with parse and safeParse, so a schema validated here is compiled once and reused — and reports the same messages the other entry points do.
The expected structure definition.
The object to validate.
The current path for error reporting (internal use).
Whether to reject extra keys not in schema.
errors (strings) and issues (structured).Builds a validator for a union whose members are told apart by a single key — the shape most API payloads use.
union tries each variant in turn, so its cost grows with the number of variants and its error lists every variant's failure. This reads the discriminant once and goes straight to the one variant that can possibly match, in constant time, and reports against that variant alone.
The variants are keyed by discriminant value, so the mapping is exact by construction — there is no literal to extract from a schema and no way to declare two variants with the same tag.
The discriminant key
The variants, keyed by discriminant value
A validator producing the union of the variants.
Expects a function to conform to specified input and output types.
The function to type-check.
The expected types for the function's parameters and return value.
Defines the expected input and output types for a function.
The expected type(s) of the function's parameters
The expected return type(s) of the function
A new function that type-checks its arguments and return value.
Registers a custom type and tracks it in the instance's type, so the
alias becomes usable in compile-time-checked schemas and resolves to R
in Infer.
This is the type-aware counterpart of registerType: same runtime
behavior, but it returns a re-typed Typer instead of void. Chain the
calls and keep the returned instance — it is the same object, only seen
through a wider type.
The alias being registered
The type the validator produces
The same instance, typed with the new alias.
const typer = new Typer()
.extend('positive', (v) => {
if (typeof v !== 'number' || v <= 0) throw new TypeError('Must be positive');
return v;
});
const schema = typer.schema({ qty: 'positive' }); // accepted
type Order = Infer<typeof schema, { positive: number }>; // { qty: number }
typer.schema({ qty: 'positiv' }); // compile error: unknown type alias
Composable form of isInstanceOf.
The instance type
The constructor to check against.
A validator producing T.
Checks if the provided value matches one or more specified types.
Overloads:
"number" narrows to number).T may be supplied.Returns true if the value matches any type, false otherwise.
Checks if the provided value matches one or more specified types.
Overloads:
"number" narrows to number).T may be supplied.The expected type for better TypeScript inference
The value to check.
One or more types to check against.
Returns true if the value matches any type, false otherwise.
Type-safe array validation
The expected element type
The value to check
Type guard for array
Checks if the provided parameter is an array of a specified type.
The expected element type
The type of elements that the array should contain.
The parameter to check.
Typed array of elements
Checks that the parameter is a syntactically valid Base64 string.
Supports both standard and URL-safe variants. Padding is required when
requirePadding is true (default).
The parameter to check
Optionalopts: { requirePadding?: boolean; urlSafe?: boolean } = {}
Options
The validated Base64 string
Type-safe boolean validation
The value to check
Type guard for boolean
Checks if the provided parameter is a number within a specified range.
The minimum value.
The maximum value.
The failing value is not in the error message: a numeric range is
exactly what guards PINs, one-time codes and amounts, and the message is
what ends up in application logs. It is on the issue's value field
instead, for callers that want to show it.
The parameter to check.
The validated number
Checks that the parameter is an instance of the given constructor.
Type-safe alternative to writing value instanceof MyClass everywhere.
The instance type produced by the constructor
The constructor to check against
The parameter to check
The validated instance
Checks that the parameter is a valid IPv6 address.
Uses the URL constructor as a permissive parser: any string accepted as
the host portion of http://[<addr>]/ is considered valid.
The parameter to check
The validated IPv6 address
Checks that the parameter is a valid ISO 8601 date string and returns
the parsed Date. Accepts the formats produced by Date#toISOString
plus reasonable variants (e.g. with timezone offsets).
The parameter to check
The parsed date (always valid)
Checks that the parameter is structurally a JSON Web Token: three base64url segments separated by dots.
This validates the shape only — it does not verify the signature or decode the claims, and must not be used as an authentication check.
The parameter to check
The validated token
Checks that the length of a string or array falls within the given bounds.
Either string or an array type
Inclusive length bounds
The parameter to check (string or array)
The validated value
Inverse of isEmpty: checks the parameter is a non-empty string, array,
Map, Set, or object.
Caller-supplied container type for narrower inference
The parameter to check
The validated non-empty value
Checks if the provided parameter is a non-empty array.
The expected element type
The parameter to check.
The validated non-empty array
Type-safe number validation
The value to check
Type guard for number
Type-safe object validation
The expected object type
The value to check
Type guard for object
Checks if the provided parameter is a valid phone number.
The parameter to check.
The validated phone number string
Checks that the parameter is a plain object (object literal or
Object.create(null)). Rejects class instances, arrays, dates, maps, etc.
The expected plain object shape
The parameter to check
The validated plain object
Checks that the parameter is a Promise (or a thenable).
The resolved promise type (caller-supplied)
The parameter to check
The validated promise
Checks that the parameter is a valid Semantic Versioning 2.0.0 string, including optional pre-release and build metadata.
The parameter to check
The validated version
Type-safe string validation
The value to check
Type guard for string
Check if the parameter matches one of the specified types.
Overloads:
"string" → string).T, which falls
back to unknown.Returns the value cast to the expected type
Check if the parameter matches one of the specified types.
Overloads:
"string" → string).T, which falls
back to unknown.The expected type for better TypeScript inference
The types to check against.
The parameter to check.
Returns the value cast to the expected type
Builds a validator accepting only the listed literal values.
The returned validator narrows to the union of those literals, so it is the composable counterpart of isOneOf.
Tuple of accepted literals
The accepted values.
A validator narrowing to values[number].
Combines two schemas. Keys of extension win where the two overlap.
The base schema
The schema layered on top
A new schema; neither source is touched.
Turns a schema into a Validator, so object shapes can be nested inside
the other combinators.
The schema is compiled once and cached like any other, so this is as fast as calling parse directly.
The returned validator is also a Standard Schema, so it can be handed straight to tRPC, Hono, TanStack Form and friends.
The schema
The shape to validate against.
Optionaloptions: { strict?: boolean } = {}
strict rejects keys the schema does not declare.
A validator producing Infer<S>, carrying ~standard.
Universal "parse" entry point. Validates value against either:
"string", "number", ...),["string", "number"] → union),Validator<T> function,Returns the value typed correctly. Throws a TypeError on failure.
No as const is needed when calling with a literal schema thanks to
the <const S> parameter — the inferred type matches the schema.
Declare the schema once, outside the hot path. Compiled checkers are cached by schema object identity, so a literal written inside a handler is a new object on every call and is recompiled every time — about an order of magnitude slower (78 ns hoisted against 873 ns inline), with nothing to show for it:
const userSchema = typer.schema({ id: 'number' }); // once
app.post('/u', (req) => typer.parse(userSchema, req.body));
app.post('/u', (req) => typer.parse({ id: 'number' }, req.body)); // recompiles
Universal "parse" entry point. Validates value against either:
"string", "number", ...),["string", "number"] → union),Validator<T> function,Returns the value typed correctly. Throws a TypeError on failure.
No as const is needed when calling with a literal schema thanks to
the <const S> parameter — the inferred type matches the schema.
Declare the schema once, outside the hot path. Compiled checkers are cached by schema object identity, so a literal written inside a handler is a new object on every call and is recompiled every time — about an order of magnitude slower (78 ns hoisted against 873 ns inline), with nothing to show for it:
const userSchema = typer.schema({ id: 'number' }); // once
app.post('/u', (req) => typer.parse(userSchema, req.body));
app.post('/u', (req) => typer.parse({ id: 'number' }, req.body)); // recompiles
Universal "parse" entry point. Validates value against either:
"string", "number", ...),["string", "number"] → union),Validator<T> function,Returns the value typed correctly. Throws a TypeError on failure.
No as const is needed when calling with a literal schema thanks to
the <const S> parameter — the inferred type matches the schema.
Declare the schema once, outside the hot path. Compiled checkers are cached by schema object identity, so a literal written inside a handler is a new object on every call and is recompiled every time — about an order of magnitude slower (78 ns hoisted against 873 ns inline), with nothing to show for it:
const userSchema = typer.schema({ id: 'number' }); // once
app.post('/u', (req) => typer.parse(userSchema, req.body));
app.post('/u', (req) => typer.parse({ id: 'number' }, req.body)); // recompiles
Universal "parse" entry point. Validates value against either:
"string", "number", ...),["string", "number"] → union),Validator<T> function,Returns the value typed correctly. Throws a TypeError on failure.
No as const is needed when calling with a literal schema thanks to
the <const S> parameter — the inferred type matches the schema.
Declare the schema once, outside the hot path. Compiled checkers are cached by schema object identity, so a literal written inside a handler is a new object on every call and is recompiled every time — about an order of magnitude slower (78 ns hoisted against 873 ns inline), with nothing to show for it:
const userSchema = typer.schema({ id: 'number' }); // once
app.post('/u', (req) => typer.parse(userSchema, req.body));
app.post('/u', (req) => typer.parse({ id: 'number' }, req.body)); // recompiles
Derives a schema with every key optional, or only the listed ones.
A type-string slot simply gains the ? marker. Every other slot kind has
no marker of its own in the schema language, so it is wrapped with
optional — which means a nested schema or array slot made
optional reports its failures as one custom issue at the slot's path,
rather than one issue per offending field. Pass the keys you actually
need if that matters.
The source schema
The schema to derive from.
A new schema; the source is untouched.
Derives a schema with every key optional, or only the listed ones.
A type-string slot simply gains the ? marker. Every other slot kind has
no marker of its own in the schema language, so it is wrapped with
optional — which means a nested schema or array slot made
optional reports its failures as one custom issue at the slot's path,
rather than one issue per offending field. Pass the keys you actually
need if that matters.
The source schema
The keys to make optional; all of them by default
A new schema; the source is untouched.
Derives a schema keeping only the listed keys.
Real applications derive schemas from each other constantly —
CreateUserDto from UserDto — and rewriting the shape by hand means
two copies that diverge at the first change.
The source schema
The keys to keep
A new schema; the source is untouched.
Builds a validator for a dictionary object: any set of keys, all values
satisfying value.
Rejects arrays and null, unlike the 'object' alias.
Keys that are dangerous to copy (__proto__, constructor,
prototype) are dropped rather than written to the result: assigning
out['__proto__'] would set the output's prototype instead of a field.
The value type
A validator producing Record<string, T>.
Register a new type in the typesMap.
The input type that the validator expects
The return type that the validator produces
// Register a positive number validator
typer.registerType<unknown, number>("positive", (value) => {
if (typeof value !== "number" || value <= 0) throw new TypeError("Must be positive");
return value;
});
// Register a string length validator
typer.registerType<unknown, string>("longString", (value) => {
if (typeof value !== "string" || value.length < 10) throw new TypeError("Must be long string");
return value;
});
Validates value without throwing. Same input shapes as parse.
Returns a discriminated union: { success: true, data } or
{ success: false, error }.
Validates value without throwing. Same input shapes as parse.
Returns a discriminated union: { success: true, data } or
{ success: false, error }.
Validates value without throwing. Same input shapes as parse.
Returns a discriminated union: { success: true, data } or
{ success: false, error }.
Validates value without throwing. Same input shapes as parse.
Returns a discriminated union: { success: true, data } or
{ success: false, error }.
Identity helper that preserves literal types of a schema declared as
a variable. Use it when you want to declare the schema once, derive
Infer<typeof schema>, and then call parse(schema, value) with
full type inference — without sprinkling as const.
Declaring the schema in a variable is also what makes it fast: compiled checkers are cached by object identity, so a schema hoisted out of the handler is compiled once, while a literal written inside it is a new object every call and is recompiled every time.
Turns any schema, validator or type alias into a Standard Schema.
Standard Schema is the common contract that lets a validation library be
accepted by tRPC, Hono, TanStack Form and Router, Nuxt and the rest,
without a per-library adapter. The returned value is still a plain
validator function, so it also keeps working everywhere a Validator
does.
Schema literals are the one shape that cannot carry ~standard on their
own — they are inert object literals owned by the caller, and Typer does
not mutate them — which is why this wrapper exists.
The validator, carrying ~standard.
Turns any schema, validator or type alias into a Standard Schema.
Standard Schema is the common contract that lets a validation library be
accepted by tRPC, Hono, TanStack Form and Router, Nuxt and the rest,
without a per-library adapter. The returned value is still a plain
validator function, so it also keeps working everywhere a Validator
does.
Schema literals are the one shape that cannot carry ~standard on their
own — they are inert object literals owned by the caller, and Typer does
not mutate them — which is why this wrapper exists.
The validator, carrying ~standard.
Turns any schema, validator or type alias into a Standard Schema.
Standard Schema is the common contract that lets a validation library be
accepted by tRPC, Hono, TanStack Form and Router, Nuxt and the rest,
without a per-library adapter. The returned value is still a plain
validator function, so it also keeps working everywhere a Validator
does.
Schema literals are the one shape that cannot carry ~standard on their
own — they are inert object literals owned by the caller, and Typer does
not mutate them — which is why this wrapper exists.
The schema
A schema object, a Validator, or a type alias (or array of aliases).
Optionaloptions: { strict?: boolean }
Schema objects only: strict rejects undeclared keys.
The validator, carrying ~standard.
Turns any schema, validator or type alias into a Standard Schema.
Standard Schema is the common contract that lets a validation library be
accepted by tRPC, Hono, TanStack Form and Router, Nuxt and the rest,
without a per-library adapter. The returned value is still a plain
validator function, so it also keeps working everywhere a Validator
does.
Schema literals are the one shape that cannot carry ~standard on their
own — they are inert object literals owned by the caller, and Typer does
not mutate them — which is why this wrapper exists.
A schema object, a Validator, or a type alias (or array of aliases).
The validator, carrying ~standard.
Converts a schema into a JSON Schema document — the input OpenAPI and Swagger tooling expects, and the main reason people reach for TypeBox.
Type strings, ? markers, | unions, arrays and nested objects all
have exact equivalents. Validator slots do not: a validator is an opaque
function, so Typer's own validators and combinators carry the fragment
they correspond to (isEmail becomes
{ type: 'string', format: 'email' }, arrayOf(…, { min: 1 }) becomes
minItems: 1), and a validator the caller wrote becomes {} — which
accepts anything.
Aliases with no JSON counterpart — symbol, function, map, set,
regexp, the buffer types, and anything registered with extend — are
in the same position. Pass unrepresentable: 'throw' in a build step to
be told about them instead of shipping a schema that quietly accepts
anything at those keys.
The schema to convert
The schema to convert.
Optionaloptions: ToJSONSchemaOptions = {}
Dialect, metadata, strictness, and the unrepresentable-slot policy.
A JSON Schema document, draft 2020-12 by default.
typer.toJSONSchema({ id: 'number', email: typer.validators.isEmail, note: 'string?' });
// {
// $schema: 'https://json-schema.org/draft/2020-12/schema',
// type: 'object',
// properties: {
// id: { type: 'number' },
// email: { type: 'string', format: 'email' },
// note: { type: ['string', 'null'] },
// },
// required: ['id', 'email'],
// }
Builds a validator for a fixed-length, heterogeneous array.
Tuple of element validators
One validator per position.
A validator producing the corresponding tuple type.
Combines multiple validators into one that succeeds if any of them succeeds. The first matching validator's result is returned.
Tuple of types produced by each validator
A new validator that returns the first matching result
Validates an object against a schema.
The expected types for each key.
The object to validate.
Substitutes a default when the value is undefined, and validates
everything else.
Pass a factory (() => T) for object or array defaults so each call gets
its own instance. A plain function default must be wrapped in a factory,
since functions are treated as factories.
The validated type
A validator producing T.
Class representing a type checker. Version: 4.0.0
Author
Michael Lavigna - https://michaellavigna.com - michael.lavigna@hotmail.it
Since
4.0.0