如何确保TypeScript接口与Zod Schema保持同步?
如何强制TypeScript接口与Zod Schema保持同步?
我有一个以TypeScript为主的现有项目,原本未对数据做运行时校验。随着API扩展及JavaScript用户的加入,我决定引入Zod进行数据运行时校验。
示例代码
import { z } from 'zod'; interface MyData { name: string; age: number; isStudent?: boolean; } const MyDataSchema = z.object({ name: z.string(), age: z.number(), isStudent: z.boolean().optional() });
我面临的难题是保持MyData接口与MyDataSchema同步。每次更新TypeScript接口都需手动更新Zod Schema,这种方式易出错且会导致不一致。
我尝试使用satisfies z.ZodType<MyTypescriptType>(示例如下),但它对可选类型的处理效果不佳。
const MyDataSchema = z.object({ name: z.string(), age: z.number(), isStudent: z.boolean().optional() }) satisfies z.ZodType<MyData>;
有没有高效的方法来强制TypeScript接口与Zod Schema同步?理想情况下,更新接口时能自动更新Schema,或至少在两者不一致时抛出错误。
解决方案
方法1:从Zod Schema自动生成TypeScript类型(推荐)
彻底避免手动同步问题,先定义Schema,再从中导出TypeScript类型:
import { z } from 'zod'; // 先编写Zod Schema const MyDataSchema = z.object({ name: z.string(), age: z.number(), isStudent: z.boolean().optional() }); // 从Schema自动推导TypeScript类型 type MyData = z.infer<typeof MyDataSchema>;
只要更新Schema,对应的TypeScript类型会自动同步,完全不需要手动维护接口。
方法2:用类型注解强制Schema匹配接口
如果必须保留手动定义的接口,直接使用z.ZodType<MyData>作为Schema的类型注解,比satisfies的约束更严格:
import { z } from 'zod'; interface MyData { name: string; age: number; isStudent?: boolean; } // 类型注解会强制Schema与接口完全匹配,不匹配则编译报错 const MyDataSchema: z.ZodType<MyData> = z.object({ name: z.string(), age: z.number(), isStudent: z.boolean().optional() });
方法3:编译期断言校验一致性
通过类型断言机制,在编译阶段检查Schema导出类型与手动接口是否完全一致:
import { z } from 'zod'; interface MyData { name: string; age: number; isStudent?: boolean; } const MyDataSchema = z.object({ name: z.string(), age: z.number(), isStudent: z.boolean().optional() }); // 定义断言类型,只要Schema与接口不匹配就会返回false type AssertMatch = z.infer<typeof MyDataSchema> extends MyData ? MyData extends z.infer<typeof MyDataSchema> ? true : false : false; // 赋值失败则表示两者不一致 const _assertSync: AssertMatch = true;
内容的提问来源于stack exchange,提问作者w1am
相关产品推荐
相关产品推荐

