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)— returnsResult<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
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 sameResult<never, ChasErr> as any other validation failure.