如何在运行时检测自定义Zod schema(如knxGroupAddress())
如何在运行时检测自定义Zod schema(如knxGroupAddress())
嘿,我来帮你搞定这个运行时检测自定义Zod Schema的问题!根据你给出的代码,我分两种常见使用场景给你讲具体的实现方式:
场景1:验证某个值是否符合你的自定义KNX Schema
这是最常用的需求,Zod本身就提供了非常顺手的方法,比如safeParse(安全验证,不会直接抛出错误)或者parse(验证失败会直接报错)。结合你的代码,具体操作如下:
首先在使用的文件里(比如你的z-extensions.ts),先导入并创建自定义Schema实例,然后用safeParse检测值:
// z-extensions.ts import { z } from "zod"; import knxGroupAddress from "./knxGroupAddress"; // 先实例化你的自定义KNX组地址Schema const knxSchemaInstance = knxGroupAddress(); // 准备测试用的地址 const validAddress = "3/12/256"; const invalidAddress = "123/45/678"; // 运行时安全检测 const validResult = knxSchemaInstance.safeParse(validAddress); if (validResult.success) { console.log("✅ 这个KNX组地址完全有效!"); // 验证通过后,validResult.data就是经过校验的字符串 } else { console.error("❌ 地址无效:", validResult.error.issues[0].message); // 如果有多个错误,可以遍历validResult.error.issues查看所有问题 } const invalidResult = knxSchemaInstance.safeParse(invalidAddress); if (!invalidResult.success) { console.error("❌ 无效地址的错误信息:", invalidResult.error.issues[0].message); }
如果你希望验证失败时直接抛出错误,用parse方法更直接:
try { knxSchemaInstance.parse("invalid-address"); console.log("地址有效!"); } catch (err) { console.error("地址无效:", (err as z.ZodError).issues[0].message); }
场景2:判断一个对象是不是你的自定义KNX Schema本身
如果你需要在运行时确认某个变量是不是你定义的knxGroupAddress类型的Schema(而非普通的ZodString),有两种靠谱的实现方式:
方法1:给Schema加自定义标记属性
这种方式最可控,完全不依赖Zod的内部实现。修改你的knxGroupAddress.tsx代码,给返回的Schema实例加一个自定义属性:
// knxGroupAddress.tsx import { z } from "zod"; const groupAddressRegex = /^\d{1,2}\/\d{1,2}\/\d{1,3}$/; const knxGroupAddress = () => { const schema = z.string().refine((val) => groupAddressRegex.test(val), { message: "Invalid KNX group address fromat, must be X/Y/Z", }); // 给Schema加一个自定义标记,方便运行时识别 (schema as any).isKnxGroupAddressSchema = true; return schema; }; export default knxGroupAddress;
然后在需要检测的地方,直接判断这个属性即可:
// z-extensions.ts import knxGroupAddress from "./knxGroupAddress"; import { z } from "zod"; const knxSchema = knxGroupAddress(); const normalStringSchema = z.string(); // 运行时检测 if ((knxSchema as any).isKnxGroupAddressSchema) { console.log("这是我们自定义的KNX组地址Schema!"); } if (!(normalStringSchema as any).isKnxGroupAddressSchema) { console.log("这只是一个普通的Zod字符串Schema,不是KNX的!"); }
方法2:通过Zod的内部_def属性判断
Zod的每个Schema实例都有一个_def内部属性,存储了Schema的定义信息。你可以通过这个属性来判断是不是你的自定义KNX Schema:
// 定义一个类型守卫函数,方便TS类型推断 function isKnxGroupAddressSchema(schema: any): schema is ReturnType<typeof knxGroupAddress> { // 先判断是不是ZodString类型 if (schema._def?.typeName !== "ZodString") return false; // 再检查有没有对应的refine规则,比如匹配错误提示信息 return schema._def.refinements?.some((ref: any) => ref.message === "Invalid KNX group address fromat, must be X/Y/Z" ); } // 使用这个函数检测 const knxSchema = knxGroupAddress(); console.log(isKnxGroupAddressSchema(knxSchema)); // 输出true console.log(isKnxGroupAddressSchema(z.string())); // 输出false
注意:_def是Zod的内部属性,官方没有承诺会永久保持这个结构,但实际项目中使用是比较稳定的。如果追求长期兼容性,更推荐第一种加自定义标记的方法。
备注:内容来源于stack exchange,提问作者fobus
相关产品推荐
相关产品推荐

