Zod Schema 是做什麼的?
每當更動涉及 Zod 時——無論是編寫 Schema、放置解析呼叫、解碼承載、或是處理錯誤——都應使用此能力。它擁有Schema 層級:形狀、解析呼叫、形狀產生的型別、產生的錯誤,以及在線路格式與領域模型間傳遞資料的編解碼器。
它不擁有四個相鄰的問題,每個問題都歸屬於各自的能力:
- 輸入是否完全不受信任,因此必須進行檢查——這是應用程式安全能力的判斷。此技能假定該判斷已做出,並說明 Zod 如何執行它。
- 存在一個鉤子供解析放入——路由處理器、伺服器函式、表單動作——這是框架能力的事實。
- 何時重新獲取、快取或失效已獲取的承載——這是伺服器狀態能力的關注點。此技能僅將解析放入其擁有的查詢函式內部。
- 元件如何接收、渲染並針對解析結果進行測試——這是元件開發能力的關注點。
如果某條規則在此技能中有對應規則,此技能會說明 Zod 機制並指定其他能力為負責方。
版本紀律。 此技能僅針對 Zod 4 編寫。Zod 3 不在支援的行列中:沒有遷移路徑、沒有 zod/v3 指南,也沒有以其 Zod 3 形式陳述的規則。Zod 3 唯一出現的地方是作為一個偵測信號——一份已被取代的慣用語列表,以便識別過時代碼並用當前形式替換。這是一個關於 Zod 4 程式碼庫的 Zod 4 規則,而非涵蓋 Zod 3。這裡的邊界比平常更重要,因為在教學、論壇文章和模型召回中,Zod 3 的答案仍然多於 Zod 4 的答案——而且大多數 Zod 3 慣用語仍然可以在 Zod 4 安裝環境下編譯,所以『它能執行』並不表示規則就是最新的。Zod 4 在其主要版本內也有變動:z.xor、z.invertCodec 和 .brand 方向參數都是在 4.0 之後才出現的。此處每個版本敏感的聲明都說明了它是針對哪個版本驗證的,並且如果某個表面已知會變動,則該規則為查閱——請參閱已安裝版本的官方文件 https://zod.dev/——而不是凍結的 API 名稱。對於此技能或其他地方關於 Zod API 的未註明版本的聲明,請保持懷疑。
針對 [email protected](發布於 2026-05-04)驗證——https://zod.dev/——並以 TypeScript 5.5+ 和 strict: true 作為先決條件。每個參考檔案都帶有各自的『驗證針對』行,說明其規則所依據的上游頁面。
超出範圍。 各種形式的 Zod 3。4.5.0-canary 版本行,此技能的任何規則均非根據此版本推導。其他驗證函式庫,除非與此技能共享邊界——涵蓋 Standard Schema 互通性,但不涵蓋 Valibot 或 ArkType 自身的 API。生成 Zod Schema 的程式碼生成工具,在它們改變你仍需手動編寫的內容時會被提及,但它們自身的配置則歸它們所有。
本文檔中的關鍵詞『必須 (MUST)』、『不得 (MUST NOT)』、『必要 (REQUIRED)』、『應 (SHALL)』、『不應 (SHALL NOT)』、『建議 (SHOULD)』、『不建議 (SHOULD NOT)』、『推薦 (RECOMMENDED)』、『可以 (MAY)』和『可選 (OPTIONAL)』應按照 RFC 2119 中的描述進行解釋。
驗證邊界
- 在資料進入的邊緣放置一次解析,並且永遠不要在內部重新解析
- 解析上游為
unknown,下游為z.infer<typeof Schema>,絕不使用手寫的介面 - 哪些問題屬於應用程式安全、框架、伺服器狀態或元件能力
- Schema 在哪些情況下會產生成本而沒有回報——內部資料、已解析的值、逐項迴圈
- 在 Zod 旁邊執行第二個驗證器,並在一個地方進行轉換
版本與套件
- 在信任頁面前區分
zod.dev(Zod 4)與v3.zod.dev(Zod 3) - 在
zod、zod/mini、zod/locales和zod/v4/*永久連結之間進行選擇 - 假設的 TypeScript 5.5+ 和
strict: true,沒有它們則推斷的可選性是不健全的 z.xor、z.invertCodec、.safeExtend、z.property和.brand方向的次版本下限- 仍可在 Zod 4 下編譯的 Zod 3 慣用語,作為過時信號
Schema 模組
const X/type X和zX命名慣例,並為每個儲存庫選擇一個- 共享的
EntityId、Timestamp和NonEmptyString基本型別,作為其他 Schema 組合的詞彙 .brand<"Name">()、其"out"/"in"/"inout"方向,以及它強制通過解析的固定資料- 使用
.shape、.extend、.safeExtend、.pick、.omit和.merge()(4.4 版在細化上會拋出錯誤)進行衍生 - 將每個 Schema 提升到模組作用域,而不是每次請求或渲染時重新建構
基本型別與格式
- 取代
z.string().x()方法的頂層z.email()、z.url()、z.uuid()和z.iso.datetime() - 選擇嚴格的
z.uuid()而非寬鬆的z.guid(),以及選擇z.httpUrl()而非z.url()用於已獲取的 URL - 專案自有格式的
z.stringFormat()和模板字面量型別的z.templateLiteral() z.int()的安全整數範圍、拒絕Infinity,以及固定寬度的z.int32()和z.float64()- 使用
z.enum()而非已棄用的z.nativeEnum(),搭配.exclude()和.extract()
物件與集合
詳見 objects-and-collections.md:
z.object()會剝離未建模的鍵,而z.strictObject()、z.looseObject()和.catchall()會改變此行為- 透過 getter 進行自我引用,以及循環錯誤所需的回傳型別註記
z.record()的兩個必要引數、詳盡的列舉鍵,以及z.partialRecord()z.tuple()中.nonempty()不再產生元組型別,以及z.file()和z.json()- 對陣列 Schema 解析一次,而不是對每個元素解析一個項目 Schema
聯合型別
詳見 unions.md:
- 使用
z.discriminatedUnion()進行縮小、提升錯誤品質,並比普通的z.union()更快解析 - 每個分支必須固定的字面鑑別器,以及 Zod 4 在其中允許的巢狀聯合和管道
- 使用
z.xor()處理匹配兩個分支的值是缺陷的情況 z.intersection()在結果無法合併時拋出普通的Error而非ZodError- 應該是一個物件的可選欄位形狀的聯合
可選性與預設值
詳見 optionality-and-defaults.md:
- 根據生產者實際發出的內容選擇
.optional()、.nullable()或.nullish() .default()在輸出型別上短路,相對於.prefault()在輸入型別上解析.catch()將解析失敗轉為備用值,以及在何種情況下這會隱藏一個漂移的生產者- 使用
.nullish().transform((v) => v ?? null)來折疊一個混合 null 和 undefined 的生產者 exactOptionalPropertyTypes對可選屬性推斷型別的影響
細化
詳見 refinements.md:
.refine()、.superRefine()和.check(),以及它們都不得拋出錯誤的規則ctx.addIssue()、z.NEVER,以及將錯誤定位到特定欄位的path- 使用
abort停止鏈式檢查,以及 4.4 版的when跳過輸入已無效的檢查 - 非同步細化會強制已組合 Schema 的所有現有呼叫者使用
.parseAsync() - 屬於領域而非 Schema 的權限、配額或唯一性規則
轉換與管道
- 驗證後的
.transform()、驗證前的z.preprocess(),以及兩個 Schema 之間的.pipe() - 當值改變但型別及其可內省性不得改變時的
.overwrite() z.input與z.output/z.infer,以及混淆兩者導致的表單和固定資料錯誤- 使用
ctx.issues.push或 4.4 版的ctx.addIssue搭配z.NEVER從轉換內部觸發失敗 - 重塑生產者資料的結束點與領域決策的起始點
編解碼器
詳見 codecs.md:
- 使用
z.codec(input, output, { decode, encode })處理邊界.transform()無法反向的情況 .decode()和.encode()及其safe*和*Async形式,以及z.invertCodec()- 已記錄的
isoDatetimeToDate、json、stringToURL和base64ToBytes模板——複製,而非匯入 - 僅在解碼時套用的預設值和
.catch(),以及會使編碼拋出非ZodError的.transform() - 不會失敗的完整編解碼器,以及它因此無法提供的形狀保證
強制轉型與配置
z.coerce.number().parse("")回傳0,以及z.coerce.boolean().parse("false")回傳truez.stringbool()作為拒絕既不為真亦不為假值(truthy/falsy)的建構- 查詢字串、表單資料和環境變數作為三個字串值來源
- 在啟動時解析一次配置並終止,而不是稍後回傳
undefined - 將秘密配置排除在日誌和客戶端 bundle 之外
解析
詳見 parsing.md:
- 當失敗是缺陷時使用
.parse(),當失敗是需要分支的結果時使用.safeParse() - 一旦 Schema 中有任何檢查是非同步,
.parseAsync()就是強制的而非可選的 - 解析回傳的深層克隆,以及它因此打破的參考身分
- 將
ZodError重新對應到領域錯誤,使 Zod 遠離領域簽名 - 記錄邊界和問題路徑,絕不記錄失敗的輸入
錯誤
詳見 errors.md:
error.issues及其code和path,以及已捨棄的.errors和.formErrors別名- 由消費者選擇的
z.treeifyError()、z.flattenError()和z.prettifyError() - 取代
message、invalid_type_error和errorMap的統一error參數 - 在 Zod 4 中反轉的優先順序——Schema、每次解析、
z.config({ customError })、語言環境 - 使用
reportInput將不受信任的輸入放入會傳遞到追蹤器或客戶端的錯誤中
中繼資料與 JSON Schema
詳見 metadata-and-json-schema.md:
.meta()、z.registry()、z.globalRegistry,以及透過宣告合併擴展GlobalMeta- 中繼資料繫結到 Schema 實例,因此
.optional()或.extend()會使其孤立 z.toJSONSchema()的target、io、unrepresentable、cycles、reused和uri選項io: "input"會產生與預設輸出視圖不同的文件- 沒有 JSON Schema 表示的
date、map、set、transform和bigint型別
模型結構化輸出
詳見 model-structured-output.md:
- 作為
generateObject或工具合約的 Schema,以及在需要原始形狀時使用satisfies z.ZodRawShape .describe()文字會作為指令而非文件傳遞給模型- 在提供者的嚴格模式下,
.nullable()能存活,而.optional()和.nullish()會被拒絕 - 重複使用
.shape.field,使模型輸出不會偏離其饋送的領域型別 - 在有限重試次數下根據
ZodError重新提示,而不是修補無效的輸出
表單
詳見 forms.md:
- 使用 Zod 專用解析器處理 Zod 自身的問題細節,或使用 Standard Schema 解析器以實現函式庫獨立性
- 使用
z.input作為表單的值和預設值,z.output作為提交處理器 - 跨欄位細化上的
path是錯誤到達正確輸入的唯一方式 - 空白數字欄位提交的空字串,以及未勾選的核取方塊發送的缺少的鍵
- 用戶端 Schema 永遠無法取代的伺服器端重新解析
資料儲存邊界
- 儲存形狀和領域模型作為兩個 Schema,並在它們之間進行轉換
- 讀寫兩半寫成一對,使重新命名的欄位不會在它們之間漂移
- 使用
.partial()處理修補程式,使用.omit().extend()處理帶有儲存標記的建立輸入 - 使用
z.instanceof()處理驅動程式的自定型別,使用z.property()限制其某個欄位 - 根據查詢深度、草稿狀態或語言環境變化的承載——以及不是解答的全可選 Schema
效能與佔用空間
詳見 performance-and-footprint.md:
- 已發布的約 14 倍、7 倍和 6.5 倍解析增益,以及約 25,000 到約 175 的型別實例化減少
zod/mini的函式式 API 和 1.88 kB 核心,以及為何伺服器不應採用它- Schema 建構應從熱路徑中提升出來,並將集合解析一次而非逐項解析
- 在已測量的路徑上,使用
.check()優於.refine(),使用鑑別聯合優於線性聯合 z.looseObject()跳過鍵剝離過程,以及它所交換的保護
安全防護
z.object()的剝離作為大量賦值保護,以及z.looseObject()重新允許的內容- 通過解析既不是 HTML 跳脫、SQL 參數化,也不是安全獲取保證
- 將
.max()放置在.regex()或昂貴的細化之前,以限制攻擊者可控制的工作 - 無界陣列、無界遞迴深度,以及會無限迴圈的循環輸入
- 允許清單回應 Schema,沒有它,私有欄位會隨承載一起離開
測試 Schema
- 為什麼斷言
z.email()拒絕"nope"測試的是 Zod 而非 Schema - 以
z.input<typeof Schema>作為固定資料型別,從觀察到的承載建構
...