Skip to main content

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

Format validators

HelperValidates
.emailRFC 5322 email address
.urlAny WHATWG-compliant URL string
.httpUrlURL with http: or https: protocol
.uuid(options?)UUID (any version by default); pass { version: 'v4' } to pin to a version
.uuidv4()Shorthand for UUID v4
.uuidv6()Shorthand for UUID v6
.uuidv7()Shorthand for UUID v7
.ulidULID (26-character lexicographically sortable ID)
.nanoid(options?)NanoID; default length 21, override with { length: n }
.ipv4IPv4 address
.ipv6IPv6 address
.cidrv4IPv4 CIDR block (e.g. 192.168.1.0/24)
.cidrv6IPv6 CIDR block (e.g. 2001:db8::/32)
.mac(options?)MAC address; delimiter defaults to :, pass { delimiter: '-' | '.' | 'none' } to override
.emojiContains at least one emoji character
.uppercaseAll characters are uppercase
.lowercaseAll 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

HelperValidates
.min(n)Length ≥ n
.max(n)Length ≤ n
.length(n)Exact length of n
.regex(re)Matches regular expression
.includes(str)Contains substring
.startsWith(str)Starts with prefix
.endsWith(str)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

HelperValidates
.base64(options?)Base64 encoding; options: { padding: 'required' | 'optional' | 'forbidden' }
.hex(options?)Hex encoding; options: { prefix?: boolean, evenLength?: boolean, case?: 'lower' | 'upper' | 'mixed' }
.jwt(options?)JWT structure; options: { validateJson?: boolean, alg?: string | 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:
HelperValidates
.isoAny ISO 8601 string
.iso.dateDate only: YYYY-MM-DD
.iso.time(options?)Time: HH:MM or HH:MM:SS[.s+]; { precision: -1 } for minute-only
.iso.datetime(options?)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

Transformers modify the value as it flows through the chain. Subsequent validators operate on the transformed value.
HelperTransforms
.trim()Removes leading and trailing whitespace
.toLowerCase()Converts to lowercase
.toUpperCase()Converts to uppercase
.normalize(options?)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() or .falsy() to accept only one side. Chain .asBool to transform the string to a boolean.
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)

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

HelperValidates
.intSafe integer (no decimal part)
.positiveGreater than 0
.negativeLess than 0
.finiteNot Infinity or -Infinity
.safeWithin Number.MAX_SAFE_INTEGER
.evenDivisible by 2
.oddNot divisible by 2
.gt(n)Greater than n
.gte(n)Greater than or equal to n
.lt(n)Less than n
.lte(n)Less than or equal to n
.between(min, max)Inclusive range
.eq(n)Strictly equal to n
.multipleOf(n)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.
HelperValidates
.trueExactly true
.falseExactly false
is.boolean(true);       // true
is.boolean.true(false); // false
is.boolean.false(false); // true

Other primitives

GuardValidates
is.bigintBigInt values
is.symbolSymbol values
is.nullnull
is.undefinedundefined
is.voidnull or undefined
is.nanNaN (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

These guards always pass at runtime but narrow the TypeScript type.
GuardType
is.unknownunknown
is.anyany
is.nevernever (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.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