Skip to main content
Guards for the core coercible types — string, number, boolean, date, bigint, object, array, and result — expose a .coerce property that adds automatic type conversion before validation. When a value does not satisfy the guard’s predicate, .coerce first converts it to the target type and then re-validates. If the value already passes without coercion, it is returned unchanged.

Basic usage

.coerce slots naturally into the chain. Any helpers added after it constrain the coerced value:

When coercion runs

Coercion takes effect in the operations that return or transform values:
  • .parse(v) — returns Result<T, ChasErr> after coercing and validating
  • .assert(v) — throws if invalid, returns the coerced value if valid
  • Standard Schema validation — used by integrations that call the Standard Schema interface
Coercion does NOT run in predicate (function-call) mode:

The type lie

When you call a .coerce guard as a plain predicate (guard(v)), it returns true if the value is coercible to the target type, but it does not actually perform the conversion. TypeScript’s type narrowing therefore reflects the coerced type in narrowing position even though the runtime value is still the original. This is an intentional design trade-off: predicates must be synchronous and allocation-free, while coercion sometimes allocates (new Date, JSON.parse, etc.). Use .parse() or .assert() whenever you need the converted value.

Coercion rules by type

is.string.coerce

String coercion is total: any value can become a string, so is.string.coerce only fails when downstream helpers (.min, .email, etc.) reject the result.

is.number.coerce


is.boolean.coerce

Boolean coercion uses an explicit list of recognized patterns rather than JavaScript’s built-in truthiness, so strings like 'false', '0', and 'no' correctly become false. Matching is case-insensitive and whitespace-trimmed.

is.date.coerce


is.bigint.coerce


is.object(shape).coerce and is.array(guard).coerce

Both object and array coercion parse JSON strings. The string must begin with { or [ respectively after trimming; any other string is passed through unchanged.

is.result().coerce

Result coercion revives a plain object ({ ok: true, value: X } or { ok: false, error: E }) back into a fully-featured Result instance, restoring all methods (.map, .mapErr, .unwrap, .unwrapErr, etc.). This is useful when a Result has been serialized to JSON and then deserialized: the round-trip strips the prototype methods, and .coerce restores them.

Chaining: coerce position matters

.coerce should appear directly after the base guard (before any constraint helpers). Constraint helpers added after .coerce run against the coerced value:

Nested coercion

Coercion composes across nested guards. If an object’s field guards also use .coerce, the inner coercions run after the outer coercion produces the object:

Failure semantics

If a value cannot be coerced, the coercer returns the original value and lets the base guard reject it normally. There are no special coercion errors: a failed coercion produces the same Result<never, ChasErr> as any other validation failure.

Summary