Zod logo

元数据和注册表

将模式与一些额外的元数据关联起来通常很有用,用于文档、代码生成、AI 结构化输出、表单验证和其他目的。

¥It's often useful to associate a schema with some additional metadata for documentation, code generation, AI structured outputs, form validation, and other purposes.

注册表

¥Registries

Zod 中的元数据通过注册表处理。注册表是模式的集合,每个模式都与一些强类型元数据相关联。要创建一个简单的注册表:

¥Metadata in Zod is handled via registries. Registries are collections of schemas, each associated with some strongly-typed metadata. To create a simple registry:

import * as z from "zod";
 
const myRegistry = z.registry<{ description: string }>();

要在此注册表中注册、查找和删除模式:

¥To register, lookup, and remove schemas from this registry:

const mySchema = z.string();
 
myRegistry.add(mySchema, { description: "A cool schema!"});
myRegistry.has(mySchema); // => true
myRegistry.get(mySchema); // => { description: "A cool schema!" }
myRegistry.remove(mySchema);
myRegistry.clear(); // wipe registry

TypeScript 强制每个架构的元数据与注册表的元数据类型匹配。

¥TypeScript enforces that the metadata for each schema matches the registry's metadata type.

myRegistry.add(mySchema, { description: "A cool schema!" }); // ✅
myRegistry.add(mySchema, { description: 123 }); // ❌

id 的特殊处理 - Zod 注册中心会特殊处理 id 属性。如果多个 Schema 注册了相同的 id 值,则会抛出 Error 错误。所有注册表,包括全局注册表,都是如此。

¥Special handling for id — Zod registries treat the id property specially. An Error will be thrown if multiple schemas are registered with the same id value. This is true for all registries, including the global registry.

.register()

注意 — 此方法的特殊之处在于它不会返回新的模式;它返回的是原始模式。其他 Zod 方法均不会执行此操作!其中包括 .meta().describe()(详见下文),它们返回一个新实例。

¥— This method is special in that it does not return a new schema; instead, it returns the original schema. No other Zod method does this! That includes .meta() and .describe() (documented below) which return a new instance.

Schema 提供了 .register() 方法,以便更方便地将其添加到注册表。

¥Schemas provide a .register() method to more conveniently add it to a registry.

const mySchema = z.string();
 
mySchema.register(myRegistry, { description: "A cool schema!" });
// => mySchema

这允许你在模式中定义元数据 "inline"。

¥This lets you define metadata "inline" in your schemas.

const mySchema = z.object({
  name: z.string().register(myRegistry, { description: "The user's name" }),
  age: z.number().register(myRegistry, { description: "The user's age" }),
})

如果注册表定义时没有元数据类型,你可以将其用作通用 "collection",无需元数据。

¥If a registry is defined without a metadata type, you can use it as a generic "collection", no metadata required.

const myRegistry = z.registry();
 
myRegistry.add(z.string());
myRegistry.add(z.number());

元数据

¥Metadata

z.globalRegistry

为了方便起见,Zod 提供了一个全局注册表 (z.globalRegistry),可用于存储用于生成 JSON Schema 或其他用途的元数据。它接受以下元数据:

¥For convenience, Zod provides a global registry (z.globalRegistry) that can be used to store metadata for JSON Schema generation or other purposes. It accepts the following metadata:

export interface GlobalMeta {
  id?: string ;
  title?: string ;
  description?: string ;
  example?: unknown ;
  examples?: 
    | unknown[] // array-style (JSON Schema)
    | Record<string, { value: unknown; [k: string]: unknown }>;  // map-style (OpenAPI)
  deprecated?: boolean ;
  [k: string]: unknown;
}

要在 z.globalRegistry 中为模式注册一些元数据:

¥To register some metadata in z.globalRegistry for a schema:

import * as z from "zod";
 
const emailSchema = z.email().register(z.globalRegistry, { 
  id: "email_address",
  title: "Email address",
  description: "Your email address",
  examples: ["first.last@example.com"]
});

.meta()

为了更方便的方法,请使用 .meta() 方法在 z.globalRegistry 中注册一个架构。

¥For a more convenient approach, use the .meta() method to register a schema in z.globalRegistry.

const emailSchema = z.email().meta({ 
  id: "email_address",
  title: "Email address",
  description: "Please enter a valid email address",
});

调用不带参数的 .meta() 将检索架构的元数据。

¥Calling .meta() without an argument will retrieve the metadata for a schema.

emailSchema.meta();
// => { id: "email_address", title: "Email address", ... }

元数据与特定的模式实例关联。这一点很重要,尤其是因为 Zod 方法是不可变的 - 它们总是返回一个新实例。

¥Metadata is associated with a specific schema instance. This is important to keep in mind, especially since Zod methods are immutable—they always return a new instance.

const A = z.string().meta({ description: "A cool string" });
A.meta(); // => { hello: "true" }
 
const B = A.refine(_ => true);
B.meta(); // => undefined

.describe()

.describe() 方法仍然存在,以便与 Zod 3 兼容,但现在推荐使用 .meta() 方法。

¥The .describe() method still exists for compatibility with Zod 3, but .meta() is now the recommended approach.

.describe() 方法是在 z.globalRegistry 中仅使用 description 字段注册架构的简写。

¥The .describe() method is a shorthand for registering a schema in z.globalRegistry with just a description field.

const emailSchema = z.email();
emailSchema.describe("An email address");
 
// equivalent to
emailSchema.meta({ description: "An email address" });

自定义注册表

¥Custom registries

你已经看到了一个自定义注册表的简单示例:

¥You've already seen a simple example of a custom registry:

import * as z from "zod";
 
const myRegistry = z.registry<{ description: string };>();

让我们看一些更高级的模式。

¥Let's look at some more advanced patterns.

引用推断类型

¥Referencing inferred types

元数据类型引用模式的推断类型通常很有价值。例如,你可能希望 examples 字段包含模式输出的示例。

¥It's often valuable for the metadata type to reference the inferred type of a schema. For instance, you may want an examples field to contain examples of the schema's output.

import * as z from "zod";
 
type MyMeta = { examples: z.$output[] };
const myRegistry = z.registry<MyMeta>();
 
myRegistry.add(z.string(), { examples: ["hello", "world"] });
myRegistry.add(z.number(), { examples: [1, 2, 3] });

特殊符号 z.$output 是对 schema 推断的输出类型(z.infer<typeof schema>)的引用。同样,你可以使用 z.$input 引用输入类型。

¥The special symbol z.$output is a reference to the schemas inferred output type (z.infer<typeof schema>). Similarly you can use z.$input to reference the input type.

限制模式类型

¥Constraining schema types

将第二个泛型传递给 z.registry(),以限制可以添加到注册表的模式类型。此注册表仅接受字符串模式。

¥Pass a second generic to z.registry() to constrain the schema types that can be added to a registry. This registry only accepts string schemas.

import * as z from "zod";
 
const myRegistry = z.registry<{ description: string }, z.ZodString>();
 
myRegistry.add(z.string(), { description: "A number" }); // ✅
myRegistry.add(z.number(), { description: "A number" }); // ❌ 
//             ^ 'ZodNumber' is not assignable to parameter of type 'ZodString' 

On this page