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

wrappers.mddocs/

0

# Schema Wrappers

1

2

Modify schemas to make them optional, nullable, or provide default values.

3

4

## Optional & Nullable

5

6

```typescript { .api }

7

function optional<T extends ZodTypeAny>(schema: T): ZodOptional<T>;

8

function nullable<T extends ZodTypeAny>(schema: T): ZodNullable<T>;

9

function nullish<T extends ZodTypeAny>(schema: T): ZodOptional<ZodNullable<T>>;

10

```

11

12

**Examples:**

13

```typescript

14

z.string().optional() // string | undefined

15

z.string().nullable() // string | null

16

z.string().nullish() // string | null | undefined

17

18

// Or use directly

19

z.optional(z.string())

20

z.nullable(z.string())

21

z.nullish(z.string())

22

23

// In objects

24

z.object({

25

name: z.string(),

26

email: z.string().optional(),

27

phone: z.string().nullable(),

28

bio: z.string().nullish(),

29

})

30

```

31

32

## Default Values

33

34

```typescript { .api }

35

function _default<T extends ZodTypeAny>(

36

schema: T,

37

defaultValue: z.infer<T> | (() => z.infer<T>)

38

): ZodDefault<T>;

39

40

// Or use method

41

schema.default(defaultValue);

42

```

43

44

**Examples:**

45

```typescript

46

z.string().default("default value")

47

z.number().default(0)

48

z.boolean().default(false)

49

z.array(z.string()).default([])

50

51

// Function defaults (evaluated each time)

52

z.date().default(() => new Date())

53

z.string().default(() => generateId())

54

55

// In objects

56

z.object({

57

name: z.string(),

58

createdAt: z.date().default(() => new Date()),

59

status: z.enum(["pending", "active"]).default("pending"),

60

})

61

```

62

63

## Prefault

64

65

Default value applied before validation (at input level).

66

67

```typescript { .api }

68

function prefault<T extends ZodTypeAny>(

69

schema: T,

70

defaultValue: z.input<T> | (() => z.input<T>)

71

): ZodPrefault<T>;

72

```

73

74

**Examples:**

75

```typescript

76

// Apply default before transformation

77

z.string()

78

.prefault("")

79

.transform((s) => s.toUpperCase())

80

81

// Difference: default vs prefault

82

const DefaultSchema = z.string().transform((s) => s.toUpperCase()).default("hello");

83

// "hello" is applied after transform, so not uppercased

84

85

const PrefaultSchema = z.string().prefault("hello").transform((s) => s.toUpperCase());

86

// "hello" is applied before transform, so becomes "HELLO"

87

```

88

89

## Catch

90

91

Provide fallback value on validation error.

92

93

```typescript { .api }

94

function catch<T extends ZodTypeAny>(

95

schema: T,

96

fallback: z.infer<T> | ((ctx: { error: ZodError; input: unknown }) => z.infer<T>)

97

): ZodCatch<T>;

98

```

99

100

**Examples:**

101

```typescript

102

// Static fallback

103

z.string().catch("fallback")

104

z.number().catch(0)

105

z.array(z.string()).catch([])

106

107

// Function fallback

108

z.string().catch((ctx) => {

109

console.log("Error:", ctx.error);

110

console.log("Input:", ctx.input);

111

return "fallback";

112

})

113

114

// In objects

115

z.object({

116

count: z.number().catch(0),

117

items: z.array(z.string()).catch([]),

118

})

119

120

// Parsing with catch

121

const schema = z.string().catch("default");

122

schema.parse(123); // "default" (instead of throwing)

123

```

124

125

## Success

126

127

Always succeeds, returns input if valid, undefined if invalid.

128

129

```typescript { .api }

130

function success<T extends ZodTypeAny>(schema: T): ZodSuccess<T>;

131

```

132

133

**Examples:**

134

```typescript

135

z.string().success()

136

z.number().success()

137

138

const schema = z.string().success();

139

schema.parse("valid"); // "valid"

140

schema.parse(123); // undefined (no error thrown)

141

```

142

143

## Readonly

144

145

Makes schema output readonly (TypeScript only).

146

147

```typescript { .api }

148

function readonly<T extends ZodTypeAny>(schema: T): ZodReadonly<T>;

149

```

150

151

**Examples:**

152

```typescript

153

z.string().readonly()

154

z.array(z.string()).readonly() // readonly string[]

155

z.object({ name: z.string() }).readonly() // { readonly name: string }

156

157

// Read-only deep

158

const schema = z.object({

159

items: z.array(z.string()).readonly(),

160

}).readonly();

161

```

162

163

## Common Patterns

164

165

```typescript

166

// API response with defaults

167

const APIResponse = z.object({

168

data: z.array(z.any()).default([]),

169

page: z.number().default(1),

170

total: z.number().default(0),

171

});

172

173

// Form with optional fields

174

const FormSchema = z.object({

175

name: z.string(),

176

email: z.string().email(),

177

phone: z.string().optional(),

178

newsletter: z.boolean().default(false),

179

});

180

181

// Config with fallbacks

182

const ConfigSchema = z.object({

183

port: z.number().catch(3000),

184

host: z.string().catch("localhost"),

185

debug: z.boolean().catch(false),

186

});

187

188

// Optional with defaults

189

z.string().optional().default("value")

190

// type: string (always defined due to default)

191

192

// Nullable with defaults

193

z.string().nullable().default("value")

194

// type: string (always defined due to default)

195

196

// Catch with logging

197

const LoggedSchema = z.number().catch((ctx) => {

198

console.error("Validation failed:", ctx.error);

199

console.error("Input was:", ctx.input);

200

return 0;

201

});

202

203

// User profile schema

204

const UserProfile = z.object({

205

name: z.string(),

206

email: z.string().email(),

207

avatar: z.string().url().optional(),

208

bio: z.string().nullable(),

209

settings: z.object({

210

theme: z.enum(["light", "dark"]).default("light"),

211

notifications: z.boolean().default(true),

212

}).default({}),

213

});

214

```

215

216

## Wrapper Combinations

217

218

```typescript

219

// Optional with default

220

z.string().optional().default("value")

221

222

// Nullable with catch

223

z.string().nullable().catch("fallback")

224

225

// All together

226

z.string()

227

.optional()

228

.nullable()

229

.default("default")

230

.catch("fallback")

231

```

232