Documentation Index
Fetch the complete documentation index at: https://docs.cbrock.dev/llms.txt
Use this file to discover all available pages before exploring further.
is.string
Validates that a value is a string. Chain helpers directly on is.string to refine or transform the value.
import { is } from 'ts-chas/guard';
is.string('hello'); // true
is.string(123); // false
| Helper | Guard Type | Validates |
|---|
.email | Property | RFC 5322 email address |
.url | Property | Any WHATWG-compliant URL string |
.httpUrl | Property | URL with http: or https: protocol |
.uuid(options?) | Factory | UUID (any version by default); pass version: 'v4' to pin to a version |
.uuidv4 | Property | Shorthand for UUID v4 |
.uuidv6 | Property | Shorthand for UUID v6 |
.uuidv7 | Property | Shorthand for UUID v7 |
.ulid | Property | ULID (26-character lexicographically sortable ID) |
.nanoid(options?) | Factory | NanoID; default length 21, override with length: n |
.ipv4 | Property | IPv4 address |
.ipv6 | Property | IPv6 address |
.cidrv4 | Property | IPv4 CIDR block (e.g. 192.168.1.0/24) |
.cidrv6 | Property | IPv6 CIDR block (e.g. 2001:db8::/32) |
.mac(options?) | Factory | MAC address; delimiter defaults to :, pass `delimiter: ’-‘ |
.emoji | Property | Contains at least one emoji character |
.uppercase | Property | All characters are uppercase |
.lowercase | Property | All characters are lowercase |
const uuidGuard = is.string.uuid({ version: 'v7' });
uuidGuard.parse('01952870-7580-7b7e-8eef-7d7e7e7e7e7e'); // Ok(string)
const macGuard = is.string.mac({ delimiter: '-' });
macGuard('AA-BB-CC-DD-EE-FF'); // true
Length and content
| Helper | Guard Type | Validates |
|---|
.min(n) | Factory | Length ≥ n |
.max(n) | Factory | Length ≤ n |
.length(n) | Factory | Exact length of n |
.regex(re) | Factory | Matches regular expression |
.includes(str) | Factory | Contains substring |
.startsWith(str) | Factory | Starts with prefix |
.endsWith(str) | Factory | Ends with suffix |
const slug = is.string.min(1).max(64).regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/);
slug.parse('my-post-title'); // Ok('my-post-title')
slug.parse(''); // Err(...)
Encoding validators
| Helper | Guard Type | Validates |
|---|
.base64(options?) | Factory | Base64 encoding; options: padding: 'required' or 'optional' or 'forbidden' |
.hex(options?) | Factory | Hex encoding; options: prefix?: boolean, evenLength?: boolean, case?: 'lower' or 'upper' or 'mixed' |
.jwt(options?) | Factory | JWT structure; options: validateJson?: boolean, alg?: string or string[] |
const hexColor = is.string.hex({ evenLength: true, case: 'lower' });
hexColor.parse('ff0099'); // Ok('ff0099')
hexColor.parse('FF0099'); // Err(...)
const jwt = is.string.jwt({ alg: ['HS256', 'RS256'] });
jwt('eyJhbGciOiJIUzI1NiJ9.e30.abc'); // true (structure only — not signature verification)
Hash validation
.hash(options?) validates a cryptographic hash string using @noble/hashes. Works in browser, Node.js, and edge runtimes.
Options:
alg — 'sha1' | 'sha256' | 'sha384' | 'sha512' | 'md5' (default: 'sha256')
enc — 'hex' | 'base64' | 'base64url' (default: 'hex')
padding — 'required' | 'optional' | 'forbidden' (only relevant for base64/base64url)
Chain .verify(plaintext) after .hash() for a timing-safe comparison that re-hashes the plaintext and compares.
import { is } from 'ts-chas/guard';
// Validate a SHA-256 hex digest
const sha256Hex = is.string.hash({ alg: 'sha256', enc: 'hex' });
sha256Hex('b94d27b9934d3e08...'); // true if correct length and hex chars
// Timing-safe verification against known plaintext
const verifyPassword = is.string.hash({ alg: 'sha256', enc: 'hex' }).verify('mysecret');
verifyPassword.parse(storedHash); // Ok(string) if storedHash matches sha256('mysecret')
JSON validators
// Validates the string is parseable JSON
const jsonStr = is.string.json({ type: 'object', maxDepth: 5 });
jsonStr.parse('{"a":1}'); // Ok('{"a":1}') — still typed as string
// Parses JSON and validates the result — output type changes
const parsedUser = is.string.parsedJson({
schema: is.object({ id: is.number, name: is.string }),
type: 'object',
});
parsedUser.parse('{"id":1,"name":"Alice"}'); // Ok({ id: 1, name: 'Alice' })
ISO date and time
Access sub-validators through .iso:
| Helper | | Validates |
|---|
.iso | Transformer Property | Any ISO 8601 string |
.iso.date | Transformer Property | Date only: YYYY-MM-DD |
.iso.time(options?) | Transformer Factory | Time: HH:MM or HH:MM:SS[.s+]; { precision: -1 } for minute-only |
.iso.datetime(options?) | TRansformer Factory | Full datetime with timezone; { offset: false } forbids it, { local: true } allows unqualified |
const eventDate = is.string.iso.date;
eventDate.parse('2026-03-30'); // Ok('2026-03-30')
eventDate.parse('March 30'); // Err(...)
const timestamp = is.string.iso.datetime({ precision: 3 }); // requires milliseconds
timestamp.parse('2026-03-30T12:00:00.000Z'); // Ok(...)
Transformers modify the value as it flows through the chain. Subsequent validators operate on the transformed value.
| Helper | Guard Type | Transforms |
|---|
.trim() | Transformer Factory | Removes leading and trailing whitespace |
.toLowerCase() | Transformer Factory | Converts to lowercase |
.toUpperCase() | Transformer Factory | Converts to uppercase |
.normalize(options?) | Transformer Factory | Unicode normalization; default form 'NFC' |
const email = is.string.trim().toLowerCase().email.max(255);
email.parse(' ALICE@EXAMPLE.COM '); // Ok('alice@example.com')
Boolean strings
.boolStr validates strings that represent boolean values. It is case-insensitive by default and accepts:
- Truthy:
true, 1, yes, y, on, active, enabled (and their capitalised/uppercase variants)
- Falsy:
false, 0, no, n, off, inactive, disabled (and their capitalised/uppercase variants)
Chain .truthy(options?) or .falsy(options?) to accept only one side. Chain .asBool to transform the string to a boolean. Pass { values: [...strings] } into .truthy() or .falsy() to use a custom allowlist.
const flag = is.string.boolStr;
flag('yes'); // true
flag('0'); // true
flag('maybe'); // false
const asBoolean = is.string.boolStr.asBool;
asBoolean.parse('yes'); // Ok(true)
asBoolean.parse('false'); // Ok(false)
const isMaybeStr = is.string.boolStr.truthy({ values: ['maybe', 'idk'] });
flag('maybe'); // true
flag('no'); // false
is.number
Validates that a value is a number (not NaN).
is.number(42); // true
is.number('42'); // false
is.number(NaN); // false — use is.nan for NaN
Helpers
| Helper | Guard Type | Validates |
|---|
.int | Property | Safe integer (no decimal part) |
.positive | Property | Greater than 0 |
.negative | Property | Less than 0 |
.finite | Property | Not Infinity or -Infinity |
.safe | Property | Within Number.MAX_SAFE_INTEGER |
.even | Property | Divisible by 2 |
.odd | Property | Not divisible by 2 |
.gt(n) | Factory | Greater than n |
.gte(n) | Factory | Greater than or equal to n |
.lt(n) | Factory | Less than n |
.lte(n) | Factory | Less than or equal to n |
.between(min, max) | Factory | Inclusive range |
.eq(n) | Factory | Strictly equal to n |
.multipleOf(n) | Factory | Divisible by n with no remainder |
const port = is.number.int.between(1, 65535);
port.parse(8080); // Ok(8080)
port.parse(0); // Err(...)
const even100 = is.number.int.multipleOf(2).lte(100);
even100.parse(42); // Ok(42)
even100.parse(43); // Err(...)
is.boolean
Validates that a value is true or false.
| Helper | Guard Type | Validates |
|---|
.true | Property | Exactly true |
.false | Property | Exactly false |
is.boolean(true); // true
is.boolean.true(false); // false
is.boolean.false(false); // true
Other primitives
| Guard | Validates |
|---|
is.bigint | BigInt values |
is.symbol | Symbol values |
is.null | null |
is.undefined | undefined |
is.void | null or undefined |
is.nan | NaN (branded as NaN type) |
is.bigint(42n); // true
is.null(null); // true
is.void(undefined); // true
is.void(null); // true
is.nan(NaN); // true
is.nan(0); // false
Type-only guards
Unknown and any always pass at runtime and all three narrow the TypeScript type.
| Guard | Type |
|---|
is.unknown | unknown |
is.any | any |
is.never | never (always fails at runtime) |
is.literal(...values)
Validates strict equality against one or more literal values. Uses Object.is semantics, so it correctly handles NaN and distinguishes 0 from -0.
const status = is.literal('active', 'inactive', 'pending');
status('active'); // true
status('deleted'); // false
const mixed = is.literal(1, 'hello', true, null);
mixed(1); // true
mixed(false); // false
is.templateLiteral(...)
Validates that a string matches a template literal pattern. Accepts a mix of string segments and guards for interpolated positions.
const route = is.templateLiteral('/users/', is.number);
route('/users/42'); // true
route('/users/abc'); // false
const method = is.templateLiteral(is.literal('GET', 'POST'), '://', is.string);
method('GET://api.example.com'); // true
method('DELETE://api.example.com'); // false
is.enum(values)
Validates that a value is one of the members of an array, TypeScript enum, or object literal.
// Array of values
const Direction = is.enum(['north', 'south', 'east', 'west'] as const);
Direction('north'); // true
Direction('up'); // false
// TypeScript enum
enum Color { Red, Green, Blue }
const color = is.enum(Color);
color(Color.Red); // true
// Object literal
const sizes = is.enum({ SM: 'sm', MD: 'md', LG: 'lg' });
sizes('sm'); // true
| Helper | Guard Type | Validates |
|---|
.exclude(values) | Transformer Factory | Excludes applicable values from the enum. |
.extract(values) | Transformer Factory | Extracts only specific values from the enum |