0
# Type Coercion
1
2
Coerce values to target types before validation. Useful for parsing form data, query parameters, and environment variables.
3
4
## Coerce Namespace
5
6
```typescript { .api }
7
namespace coerce {
8
function string(params?: { description?: string; errorMap?: ZodErrorMap }): ZodString;
9
function number(params?: { description?: string; errorMap?: ZodErrorMap }): ZodNumber;
10
function boolean(params?: { description?: string; errorMap?: ZodErrorMap }): ZodBoolean;
11
function bigint(params?: { description?: string; errorMap?: ZodErrorMap }): ZodBigInt;
12
function date(params?: { description?: string; errorMap?: ZodErrorMap }): ZodDate;
13
}
14
```
15
16
## String Coercion
17
18
```typescript
19
z.coerce.string()
20
// Converts any value to string using String()
21
22
z.coerce.string().parse(42); // "42"
23
z.coerce.string().parse(true); // "true"
24
z.coerce.string().parse(null); // "null"
25
z.coerce.string().parse(undefined); // "undefined"
26
27
// With validation
28
z.coerce.string().email()
29
z.coerce.string().min(3).max(20)
30
```
31
32
## Number Coercion
33
34
```typescript
35
z.coerce.number()
36
// Converts values to number using Number()
37
38
z.coerce.number().parse("42"); // 42
39
z.coerce.number().parse("3.14"); // 3.14
40
z.coerce.number().parse(true); // 1
41
z.coerce.number().parse(false); // 0
42
z.coerce.number().parse("invalid"); // NaN (fails validation)
43
44
// With validation
45
z.coerce.number().int().positive()
46
z.coerce.number().min(0).max(100)
47
```
48
49
## Boolean Coercion
50
51
```typescript
52
z.coerce.boolean()
53
// Converts values to boolean using Boolean()
54
55
z.coerce.boolean().parse("true"); // true
56
z.coerce.boolean().parse("false"); // true (any non-empty string is truthy)
57
z.coerce.boolean().parse(1); // true
58
z.coerce.boolean().parse(0); // false
59
z.coerce.boolean().parse(""); // false
60
```
61
62
## BigInt Coercion
63
64
```typescript
65
z.coerce.bigint()
66
// Converts values to bigint using BigInt()
67
68
z.coerce.bigint().parse("42"); // 42n
69
z.coerce.bigint().parse(42); // 42n
70
z.coerce.bigint().parse("123456789012345678901234567890"); // 123456789012345678901234567890n
71
72
// With validation
73
z.coerce.bigint().positive()
74
z.coerce.bigint().min(0n).max(1000000000n)
75
```
76
77
## Date Coercion
78
79
```typescript
80
z.coerce.date()
81
// Converts values to Date using new Date()
82
83
z.coerce.date().parse("2024-01-01"); // Date object
84
z.coerce.date().parse(1704067200000); // Date from timestamp
85
z.coerce.date().parse(new Date()); // Already a Date
86
87
// With validation
88
z.coerce.date().min(new Date("2020-01-01"))
89
z.coerce.date().max(new Date())
90
```
91
92
## Common Patterns
93
94
```typescript
95
// Form data parsing
96
const FormSchema = z.object({
97
name: z.string(),
98
age: z.coerce.number().int().positive(),
99
subscribe: z.coerce.boolean(),
100
createdAt: z.coerce.date(),
101
});
102
103
// Query parameters
104
const QuerySchema = z.object({
105
page: z.coerce.number().int().min(1).default(1),
106
limit: z.coerce.number().int().min(1).max(100).default(10),
107
sort: z.string().optional(),
108
});
109
110
// Environment variables
111
const EnvSchema = z.object({
112
PORT: z.coerce.number().int().positive().default(3000),
113
DEBUG: z.coerce.boolean().default(false),
114
DATABASE_URL: z.string().url(),
115
MAX_CONNECTIONS: z.coerce.number().int().positive().default(10),
116
});
117
118
const env = EnvSchema.parse(process.env);
119
120
// API with coercion
121
const APIParamsSchema = z.object({
122
id: z.coerce.number().int(),
123
includeDeleted: z.coerce.boolean().default(false),
124
since: z.coerce.date().optional(),
125
});
126
127
// URL search params
128
const searchParams = new URLSearchParams(window.location.search);
129
const params = QuerySchema.parse(Object.fromEntries(searchParams));
130
131
// CSV parsing
132
const CSVRowSchema = z.object({
133
id: z.coerce.number(),
134
name: z.string(),
135
price: z.coerce.number(),
136
inStock: z.coerce.boolean(),
137
date: z.coerce.date(),
138
});
139
```
140
141
## Coercion vs Transformation
142
143
```typescript
144
// Coercion (before validation)
145
z.coerce.number().min(10)
146
// Input "5" -> Coerce to 5 -> Validate min(10) -> Fail
147
148
// Transformation (after validation)
149
z.string().transform((s) => Number(s)).min(10)
150
// Input "5" -> Validate as string -> Transform to 5 -> Fail at min(10)
151
152
// Preprocess (custom coercion)
153
z.preprocess((val) => Number(val), z.number().min(10))
154
// Similar to coerce but with custom logic
155
```
156
157
## When to Use Coercion
158
159
- **Form data**: All form inputs are strings
160
- **Query parameters**: URL params are strings
161
- **Environment variables**: All env vars are strings
162
- **CSV/TSV parsing**: All values are strings
163
- **API params**: Numeric IDs passed as strings
164
165
**Note**: Be careful with boolean coercion - any truthy value becomes `true`. For form checkboxes, consider custom validation:
166
167
```typescript
168
const CheckboxSchema = z.preprocess(
169
(val) => val === "true" || val === true,
170
z.boolean()
171
);
172
```
173