如何将 TypeScript 类型守卫与 Zod 数据验证结合使用?

摘要:我见过许多因为运行时数据不匹配而导致的崩溃,也曾写过无数防御性代码和 any 断言,哈哈 😄。TypeScript 的类型安全本来就不该止步于编译期。直到遇见 Zod,Zod 不仅是一个验证库,它为 Type
我见过许多因为运行时数据不匹配而导致的崩溃,也曾写过无数防御性代码和 any 断言,哈哈 😄。TypeScript 的类型安全本来就不该止步于编译期。直到遇见 Zod,Zod 不仅是一个验证库,它为 TypeScript 带来运行时安全,是目前最优雅、最彻底的解决方案。 我们为何需要 Zod? TypeScript 最让人上瘾的地方在于编译时类型检查,但这也是它的最大谎言,因为类型在运行时彻底消失,你需要小心小心再小心,使用 TypeScript 并不代表类型安全。 interface User { name: string; age: number; role: 'admin' | 'user'; } fetch('/api/user').then(res => res.json()).then((data: User) => { // 编译通过,但如果 data.role 返回的是 "administrator",运行会报错 console.log(data.role.toUpperCase()); }); 而 Zod 的答案是:只定义一次 Schema,既得到运行时验证,又得到完美的 TypeScript 类型。 const UserSchema = z.object({ name: z.string(), age: z.number(), role: z.enum(['admin', 'user']), }); type User = z.infer<typeof UserSchema>; 通过 Schema 推断出完美类型 User,无需二次声明。这样, UserSchema 用于运行时验证,User 用于类型推断。 Zod 入门 npm install zod import { z } from 'zod'; // 基础类型 const StringSchema = z.string(); const NumberSchema = z.number().int().positive(); 核心 API:parse 和 safeParse,我建议优先使用 .safeParse()。 const schema = z.string(); try { const result = schema.parse(123); console.log(result); } catch (error) { console.error('验证失败:', error.errors); } parse 抛出 ZodError, 你需要通过 try catch 捕获错误,否则导致程序崩溃。 const schema = z.string(); const result = schema.safeParse(123); if (result.success) { console.log('验证成功:', result.data); } else { console.log('验证失败:', result.error.errors); } safeParse 返回 { success: true, data: T } 或 { success: false, error: ZodError },你可以通过 success 判断是否验证成功,然后通过 data 获取验证后的数据,或者通过 error.errors 获取错误信息, 这样你可以优雅地处理错误。
阅读全文