Zod coerce is a feature that automatically converts input values to the desired data type before applying validation.
In real applications, most user input and query parameters arrive as strings, even when they represent numbers or booleans.
Without coercion, you’d need to manually convert every value before validation — which is repetitive and error-prone.
Try it out: Without Coersion
const schema = z.number();
const input = { age: "25" }; // form data
schema.parse(input.age); // Error: Expected number, received string
Try it out: With Coersion
const schema = z.coerce.number();
const input = { age: "25" };
schema.parse(input.age); // 25 (auto-converted)
Error Handling in Zod Coerce
const schema = z.coerce.number({
required_error: "Age is required",
invalid_type_error: "Age must be a valid number",
}).min(18, "You must be 18 or older");
try {
schema.parse("abc"); // invalid input
} catch (err) {
console.log(err.errors[0].message);
// "Age must be a valid number"
}
z.coerce.number()
tries to convert"abc"
into a number.- Since it becomes
NaN
, Zod throws an error. - The
invalid_type_error
defines a custom error message for coercion failure. - You can also use
.min()
,.max()
, etc., to add validation-specific messages.
Edge Cases in Zod Coerce
The Edge Cases section demonstrates how z.coerce
behaves with different data types in real-world scenarios. It shows how Zod handles conversion of strings, numbers, booleans, dates, and BigInts, including unusual inputs like empty strings, null, or undefined.
Understanding these behaviors ensures consistent, predictable validation across forms and API inputs while avoiding common pitfalls.
String:
const schema = z.coerce.string();
Using z.coerce.string()
, any input value is automatically converted into a string. It can coerce numbers into text like "123"
, booleans into "true"
or "false"
, and even handle empty strings.
Other primitive values such as null
, undefined
, or symbols are also converted into their string representations, making z.coerce.string()
highly useful for normalizing mixed input data into consistent string formats.
Number:
const schema = z.coerce.number();
z.coerce.number()
automatically converts any input that can be interpreted as a number.- Coerces numeric strings like
"25"
→25
. - Converts booleans:
true
→1
,false
→0
. - Converts empty strings (
""
) →0
. - Converts
null
→0
, andundefined
→NaN
. - Ideal for form or API inputs where numeric fields are received as strings.
- Ensures consistent and predictable number types across your application.
Boolean:
const schema = z.coerce.boolean();
z.coerce.boolean()
converts input values using JavaScript’s truthy/falsy rules.- Coerces numbers:
1
→true
,0
→false
. - Coerces empty strings (
""
) →false
, non-empty strings (like"false"
) →true
. - Coerces
null
andundefined
→false
. - Useful for normalizing checkbox, toggle, or flag inputs from forms or APIs.
Date:
const schema = z.coerce.date();
z.coerce.date()
converts input values into JavaScriptDate
objects.- Coerces ISO date strings like
"2025-10-08"
→Date("2025-10-08")
. - Converts timestamps (numbers) like
1696752000000
→ correspondingDate
object. - Converts invalid strings (e.g.,
"not-a-date"
) → throws a validation error. - Converts empty strings (
""
) andundefined
→ invalid date error. - Ideal for form or API inputs where date fields are sent as strings.
- Ensures consistent date handling across your application without manual parsing.
Zod Coerce to Array
There is no z.coerce.array()
in Zod.
BigInt:
const schema = z.coerce.bigint();
z.coerce.bigint()
converts inputs intoBigInt
.- Numeric strings like
"123"
→123n
. - Numbers like
123
→123n
. - Boolean values:
true
→1n
,false
→0n
. - Empty string (
""
) →0n
. null
orundefined
→ throws an error.- Ideal for safely handling very large integers from strings, numbers, or boolean-like inputs.
Zod Coerce to Enum
There is no z.coerce.enum()
in Zod.
Summary
Zod’s coerce
feature simplifies input validation by automatically converting values to the desired type before applying schema rules. It is particularly useful when dealing with user input or API data that often arrives as strings.
With z.coerce
, you can handle numbers, strings, booleans, dates, and BigInts consistently, reducing repetitive manual conversions.
Custom error messages and additional validations like .min()
or .max()
work seamlessly with coercion. While Zod supports coercion for most primitive types, arrays and enums are not directly coercible.
Tired of juggling input conversions and validation logic? Zod offers much more than coercion. Check out our Zod Tutorial to streamline all your schema validation challenges.