# Objects

URL: https://caijiao.org/zod/objects
Source: docs/zod/objects.md
Description: 对象模式的定义和验证，包括嵌套对象、可选属性、严格模式和动态键的处理

Zod 提供了强大的对象验证功能。

## 基本用法

```ts
import { z } from "zod";

const User = z.object({
  username: z.string(),
  age: z.number(),
  email: z.string().email(),
  isAdmin: z.boolean().optional(),
});

type User = z.infer<typeof User>;
// { username: string; age: number; email: string; isAdmin?: boolean }
```

## 访问对象属性

使用 `.shape` 访问对象的属性模式：

```ts
const User = z.object({
  username: z.string(),
  age: z.number(),
});

User.shape.username; // 返回字符串模式
User.shape.age; // 返回数字模式
```

## 扩展对象

使用 `.extend` 添加新属性：

```ts
const User = z.object({
  username: z.string(),
});

const AdminUser = User.extend({
  isAdmin: z.boolean(),
  permissions: z.array(z.string()),
});
```

## 合并对象

使用 `.merge` 合并两个对象模式：

```ts
const BaseUser = z.object({
  id: z.string(),
  username: z.string(),
});

const UserDetails = z.object({
  age: z.number(),
  email: z.string().email(),
});

const FullUser = BaseUser.merge(UserDetails);
// 等同于：
// z.object({
//   id: z.string(),
//   username: z.string(),
//   age: z.number(),
//   email: z.string().email(),
// })
```

## 部分选择和忽略

使用 `.pick` 和 `.omit` 选择或忽略特定属性：

```ts
const User = z.object({
  id: z.string(),
  username: z.string(),
  age: z.number(),
  email: z.string(),
});

// 只选择某些字段
const UserBasics = User.pick({ username: true, age: true });
// { username: string; age: number }

// 忽略某些字段
const UserWithoutId = User.omit({ id: true });
// { username: string; age: number; email: string }
```

## 可选字段

使用 `.partial` 使所有字段变为可选：

```ts
const User = z.object({
  username: z.string(),
  age: z.number(),
});

const PartialUser = User.partial();
// { username?: string; age?: number }

// 深度可选
const DeepPartialUser = User.deepPartial();
```

## 严格模式

默认情况下，Zod 会剔除未定义的字段。你可以使用 `.strict()` 禁止额外字段：

```ts
const User = z.object({
  username: z.string(),
}).strict();

User.parse({
  username: "bob",
  extra: "field", // 将抛出错误
});

// 或使用 .passthrough() 保留额外字段
const FlexibleUser = z.object({
  username: z.string(),
}).passthrough();

FlexibleUser.parse({
  username: "bob",
  extra: "field", // 将被保留
});
```

## 通配符属性

使用 `.catchall` 定义未知键的类型：

```ts
const NumberCache = z.object({
  id: z.string(),
}).catchall(z.number());

// 等同于 { [k: string]: number } & { id: string }

NumberCache.parse({
  id: "xyz123",
  count: 42,
  amount: 123,
}); // 通过
```
