# Tuples

URL: https://caijiao.org/zod/tuples
Source: docs/zod/tuples.md
Description: 菜鸟教程官网提供HTML、CSS、JavaScript、Python等编程教程，覆盖开发问题库、Reference速查、AI Coding、SEO建站和在线工具，帮助零基础与开发者系统学习并解决实际开发问题。

Zod 提供了创建和验证元组的功能。元组是固定长度的数组，其中每个位置可以有不同的类型。

## 基本用法

```ts
import { z } from "zod";

// 创建元组模式
const StringNumberTuple = z.tuple([z.string(), z.number()]);
type StringNumberTuple = z.infer<typeof StringNumberTuple>; // [string, number]

// 验证
StringNumberTuple.parse(["hello", 42]); // 通过
StringNumberTuple.parse(["hello", "world"]); // 失败
StringNumberTuple.parse([42, 42]); // 失败
```

## 可选元素

你可以使用 `.rest()` 方法来指定剩余元素的类型：

```ts
const StringNumberRest = z.tuple([z.string(), z.number()]).rest(z.boolean());

// 验证
StringNumberRest.parse(["hello", 42]); // 通过
StringNumberRest.parse(["hello", 42, true]); // 通过
StringNumberRest.parse(["hello", 42, true, false]); // 通过
StringNumberRest.parse(["hello", 42, "true"]); // 失败
```

## 复杂元组

元组可以包含任何 Zod 模式：

```ts
// 对象元组
const UserTuple = z.tuple([
  z.object({ id: z.string() }),
  z.object({ name: z.string() }),
]);

// 联合类型元组
const UnionTuple = z.tuple([
  z.union([z.string(), z.number()]),
  z.boolean(),
]);

// 嵌套元组
const NestedTuple = z.tuple([
  z.tuple([z.string(), z.number()]),
  z.boolean(),
]);
```

## 元组长度

元组的长度是固定的（除非使用 `.rest()`）：

```ts
const Tuple = z.tuple([z.string(), z.number()]);

Tuple.parse(["hello", 42]); // 通过
Tuple.parse(["hello"]); // 失败：元组太短
Tuple.parse(["hello", 42, true]); // 失败：元组太长
```

## 元组元素访问

你可以使用数组索引访问元组的元素：

```ts
const Tuple = z.tuple([z.string(), z.number(), z.boolean()]);

// 在 TypeScript 中
type First = z.infer<typeof Tuple>[0]; // string
type Second = z.infer<typeof Tuple>[1]; // number
type Third = z.infer<typeof Tuple>[2]; // boolean
```

## 自定义错误消息

你可以为元组的每个元素提供自定义错误消息：

```ts
const Tuple = z.tuple([
  z.string({
    invalid_type_error: "第一个元素必须是字符串",
  }),
  z.number({
    invalid_type_error: "第二个元素必须是数字",
  }),
]);

// 验证
Tuple.parse([42, "hello"]); // 失败，带有自定义错误消息
```
