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

utilities.mddocs/

0

# Type Inference and Utilities

1

2

Extract TypeScript types from schemas and utilities for schema manipulation.

3

4

## Type Inference

5

6

```typescript { .api }

7

// Output type (after transformations)

8

type infer<T extends ZodType> = T["_output"];

9

type output<T extends ZodType> = T["_output"];

10

11

// Input type (before transformations)

12

type input<T extends ZodType> = T["_input"];

13

```

14

15

**Examples:**

16

```typescript

17

const UserSchema = z.object({

18

name: z.string(),

19

age: z.number(),

20

});

21

22

type User = z.infer<typeof UserSchema>;

23

// { name: string; age: number }

24

25

type UserInput = z.input<typeof UserSchema>;

26

// Same as output for simple schemas

27

28

// With transformation

29

const TransformSchema = z.string().transform((s) => s.length);

30

31

type Input = z.input<typeof TransformSchema>; // string

32

type Output = z.output<typeof TransformSchema>; // number

33

type Inferred = z.infer<typeof TransformSchema>; // number (same as output)

34

```

35

36

## Schema Cloning

37

38

```typescript { .api }

39

function clone<T extends ZodTypeAny>(

40

schema: T,

41

def?: Partial<T["_def"]>,

42

params?: { parent?: boolean }

43

): T;

44

```

45

46

**Examples:**

47

```typescript

48

const original = z.string();

49

const cloned = z.clone(original);

50

51

// Clone with modifications

52

const modified = z.clone(original, {

53

description: "New description",

54

});

55

```

56

57

## Configuration

58

59

```typescript { .api }

60

function config(options?: Partial<ZodConfig>): ZodConfig;

61

62

interface ZodConfig {

63

locale?: Locale;

64

errorMap?: ZodErrorMap;

65

}

66

```

67

68

**Examples:**

69

```typescript

70

// Global error map

71

z.config({

72

errorMap: (issue, ctx) => {

73

if (issue.code === z.ZodIssueCode.invalid_type) {

74

return { message: "Custom type error message" };

75

}

76

return { message: ctx.defaultError };

77

},

78

});

79

80

// Global locale

81

z.config({

82

locale: z.locales.es(),

83

});

84

85

// Combined

86

z.config({

87

locale: z.locales.fr(),

88

errorMap: customErrorMap,

89

});

90

```

91

92

## Schema Utilities

93

94

```typescript

95

// Check schema type

96

schema instanceof z.ZodString

97

schema instanceof z.ZodNumber

98

schema instanceof z.ZodObject

99

100

// Get schema _def

101

schema._def

102

103

// Schema methods available on all types

104

schema.optional()

105

schema.nullable()

106

schema.default(value)

107

schema.catch(fallback)

108

schema.refine(fn, msg)

109

schema.transform(fn)

110

schema.parse(data)

111

schema.safeParse(data)

112

```

113

114

## Type Guards and Helpers

115

116

```typescript

117

// Type narrowing with safeParse

118

const result = schema.safeParse(data);

119

120

if (result.success) {

121

// result.data is typed correctly

122

const validData: OutputType = result.data;

123

} else {

124

// result.error is ZodError

125

const error: z.ZodError = result.error;

126

}

127

128

// Extract object shape

129

const UserSchema = z.object({

130

name: z.string(),

131

age: z.number(),

132

});

133

134

type UserShape = typeof UserSchema.shape;

135

// { name: ZodString; age: ZodNumber }

136

137

// Extract enum options

138

const StatusSchema = z.enum(["pending", "active", "completed"]);

139

type StatusOptions = typeof StatusSchema.options;

140

// ["pending", "active", "completed"]

141

142

const statusEnum = StatusSchema.enum;

143

// { pending: "pending", active: "active", completed: "completed" }

144

```

145

146

## Common Patterns

147

148

```typescript

149

// Reusable type inference

150

const createSchema = () => z.object({

151

id: z.string(),

152

name: z.string(),

153

});

154

155

type InferredType = z.infer<ReturnType<typeof createSchema>>;

156

157

// Generic schema function

158

function createAPISchema<T extends z.ZodTypeAny>(dataSchema: T) {

159

return z.object({

160

success: z.boolean(),

161

data: dataSchema,

162

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

163

});

164

}

165

166

const UserAPISchema = createAPISchema(UserSchema);

167

type UserAPIResponse = z.infer<typeof UserAPISchema>;

168

169

// Extract nested types

170

const NestedSchema = z.object({

171

user: z.object({

172

profile: z.object({

173

name: z.string(),

174

}),

175

}),

176

});

177

178

type Nested = z.infer<typeof NestedSchema>;

179

type User = Nested["user"];

180

type Profile = Nested["user"]["profile"];

181

182

// Conditional schema creation

183

function createSchemaWithOptional<T extends boolean>(

184

includeOptional: T

185

): T extends true

186

? z.ZodObject<{ name: z.ZodString; email: z.ZodOptional<z.ZodString> }>

187

: z.ZodObject<{ name: z.ZodString }> {

188

// Implementation

189

}

190

191

// Branded types

192

type UserId = z.infer<typeof z.string()> & { readonly __brand: unique symbol };

193

194

const UserIdSchema = z.string().refine(

195

(val): val is UserId => /^user_/.test(val)

196

);

197

```

198

199

## Advanced Type Inference

200

201

```typescript

202

// Infer from pipe

203

const PipeSchema = z.pipe(z.string(), z.number());

204

type PipeInput = z.input<typeof PipeSchema>; // string

205

type PipeOutput = z.output<typeof PipeSchema>; // number

206

207

// Infer from union

208

const UnionSchema = z.union([

209

z.object({ type: z.literal("a"), value: z.string() }),

210

z.object({ type: z.literal("b"), value: z.number() }),

211

]);

212

213

type Union = z.infer<typeof UnionSchema>;

214

// { type: "a"; value: string } | { type: "b"; value: number }

215

216

// Infer from discriminated union

217

const DiscriminatedSchema = z.discriminatedUnion("type", [

218

z.object({ type: z.literal("success"), data: z.any() }),

219

z.object({ type: z.literal("error"), error: z.string() }),

220

]);

221

222

type Result = z.infer<typeof DiscriminatedSchema>;

223

224

// Recursive type inference

225

interface Category {

226

name: string;

227

children: Category[];

228

}

229

230

const CategorySchema: z.ZodType<Category> = z.lazy(() =>

231

z.object({

232

name: z.string(),

233

children: z.array(CategorySchema),

234

})

235

);

236

237

type InferredCategory = z.infer<typeof CategorySchema>; // Category

238

```

239

240

## Utility Types

241

242

```typescript

243

// Partial object schema

244

type PartialUser = z.infer<typeof UserSchema.partial()>;

245

246

// Pick from object

247

type UserNameEmail = z.infer<typeof UserSchema.pick({ name: true, email: true })>;

248

249

// Omit from object

250

type UserWithoutPassword = z.infer<typeof UserSchema.omit({ password: true })>;

251

252

// Extended schema

253

type ExtendedUser = z.infer<typeof UserSchema.extend({ role: z.string() })>;

254

255

// Merged schema

256

type MergedUser = z.infer<typeof UserSchema.merge(ProfileSchema)>;

257

258

// Array element type

259

const ArraySchema = z.array(z.string());

260

type Element = z.infer<typeof ArraySchema>[number]; // string

261

262

// Object key type

263

const ObjSchema = z.object({ a: z.string(), b: z.number() });

264

type Keys = keyof z.infer<typeof ObjSchema>; // "a" | "b"

265

```

266