Skip to main content

zod

Zod v4 schema validation 最佳實踐指南。當需要定義 schema、驗證/解析 JSON 資料、type inference、或處理 unknown data 時使用。

Zur Installation springen

Quellinformationen

Repository
recca0120/codeatlas
Letzte Quellaktivität
28. März 2026 um 07:13
Erkannte Sprache von SKILL.md
Chinesisch
Sterne
1
Forks
0

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
zod
description
Zod v4 schema validation 最佳實踐指南。當需要定義 schema、驗證/解析 JSON 資料、type inference、或處理 unknown data 時使用。
# Zod v4 Guide (v4.3+) ## 安裝 ```bash npm install zod # v4 is latest ``` 需要 TypeScript 5.5+ 且 `"strict": true`。 ## Import ```ts import { z } from "zod"; ``` ## Primitives ```ts z.string() z.number() z.boolean() z.null() z.undefined() z.unknown() z.int() z.int32() z.float64() ``` ## Objects ```ts // 預設 strip unknown keys const User = z.object({ name: z.string(), age: z.number(), }); // 嚴格模式:拒絕 unknown keys const StrictUser = z.strictObject({ name: z.string() }); // 寬鬆模式:保留 unknown keys const LooseUser = z.looseObject({ name: z.string() }); ``` ### Object 操作 ```ts User.extend({ email: z.email() }); // 效能更好的寫法: z.object({ ...User.shape, email: z.email() }); User.pick({ name: true }); User.omit({ age: true }); User.partial(); User.required(); User.keyof(); ``` ## Arrays ```ts z.array(z.string()) z.array(z.string()).min(1).max(10) ``` ## Enums ```ts const Color = z.enum(["red", "green", "blue"]); // TypeScript enums(v4 新增,取代 z.nativeEnum) enum Direction { Up, Down } z.enum(Direction); ``` ## Optional / Nullable / Default ```ts z.string().optional() // string | undefined z.string().nullable() // string | null z.string().nullish() // string | null | undefined z.string().default("hi") // 預設值 z.number().catch(0) // parse 失敗時的 fallback ``` ## parse vs safeParse ```ts // 失敗時拋出 ZodError const data = schema.parse(input); // 不拋錯,回傳 discriminated union const result = schema.safeParse(input); if (result.success) { result.data; // typed } else { result.error; // ZodError } ``` ## Type Inference ```ts type User = z.infer<typeof User>; // output type type UserInput = z.input<typeof User>; // input type(transforms 前) ``` **最佳實踐**:從 schema 推導 type(`z.infer`),不要另外定義 interface — single source of truth。 ## String Formats(v4 新增 top-level) ```ts z.email() z.url() z.uuid() z.iso.date() z.iso.datetime() // 舊寫法 z.string().email() 已 deprecated ``` ## Transforms & Pipes ```ts z.string().transform(val => val.length) // string → number z.coerce.number() // String(input) → number ``` ## Refinements ```ts z.string().refine(val => val.length <= 255, { error: "Too long" }); // 跨欄位驗證 z.object({ password: z.string(), confirm: z.string(), }).refine(d => d.password === d.confirm, { error: "Passwords don't match", path: ["confirm"], }); ``` ## Recursive Schemas(v4 用 getter,不需要 z.lazy) ```ts const Category = z.object({ name: z.string(), get children() { return z.array(Category); }, }); ``` ## Branded Types ```ts const UserId = z.string().brand<"UserId">(); type UserId = z.infer<typeof UserId>; ``` ## Error 自訂(v4 改用 error 參數) ```ts // v3: message / invalid_type_error / required_error(已移除) // v4: z.string({ error: "Must be string" }); z.string({ error: (issue) => issue.input === undefined ? "Required" : "Invalid" }); ``` ## JSON Schema 轉換(v4 新增) ```ts const jsonSchema = z.toJSONSchema(schema); ``` ## 最佳實踐 1. **Single source of truth**:schema 定義一次,type 用 `z.infer` 推導 2. **解析 unknown JSON**:用 `.safeParse()` 處理不信任的外部資料 3. **Unknown keys**:預設 `z.object()` 會 strip — 適合清理舊格式資料 4. **Union 效能**:大量 union 用 `z.discriminatedUnion()`(O(1) lookup) 5. **Composition**:用 spread `{ ...Base.shape }` 優於 `.extend()` chain 6. **Nullable fields**:`.nullable()` 對應 `null`,`.optional()` 對應 `undefined`
Auf GitHub ansehen