or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-schemas.mdcoercion.mdcollections.mderrors.mdindex.mdiso-datetime.mdjson-schema.mdlocales.mdnumber-formats.mdparsing.mdprimitives.mdrefinements.mdstring-formats.mdtransformations.mdunions-intersections.mdutilities.mdwrappers.md

coercion.mddocs/

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