如何从Zod Schema推断泛型Message<T>类型?
解决方案:用Zod实现泛型消息类型与Schema
要实现类似原泛型Message<T>的效果,你需要把消息Schema定义成泛型工厂函数,通过传入特定的Body Schema来生成对应的完整消息Schema,同时自动推断出泛型类型。这样既保留Zod的校验能力,又能获得和原代码一致的类型灵活性。
完整代码示例
import { z } from "zod"; // 基础消息体Schema,对应原MessageBody类型 const BaseMessageBodySchema = z.union([z.string(), z.object({}), z.undefined()]); // 泛型工厂函数:传入特定body Schema,返回对应的消息Schema const createMessageSchema = <T extends z.ZodTypeAny>(bodySchema: T = BaseMessageBodySchema as T) => { return z.object({ body: bodySchema, }); }; // 泛型Message类型:从工厂函数返回的Schema中自动推断 type Message<T extends z.ZodTypeAny = typeof BaseMessageBodySchema> = z.infer<ReturnType<typeof createMessageSchema<T>>>; // ---------------------- 使用示例 ---------------------- // 定义特定消息体的Schema与类型 const SpecificBodySchema = z.object({ specific: z.string(), }); type SpecificBody = z.infer<typeof SpecificBodySchema>; // 1. 生成带校验的特定消息Schema const specificMessageSchema = createMessageSchema(SpecificBodySchema); // 校验示例:通过校验 specificMessageSchema.parse({ body: { specific: "hello" } }); // 校验示例:失败(缺少specific字段) specificMessageSchema.parse({ body: {} }); // 2. 直接使用泛型类型,和原代码的Message<SpecificBody>完全一致 const message: Message<typeof SpecificBodySchema> = { body: { specific: "test" }, };
关键说明
- 工厂函数
createMessageSchema允许你传入任意符合约束的Body Schema,动态生成对应的消息校验规则。 - 泛型
Message<T>通过z.infer和ReturnType组合,自动从传入的Body Schema中推断出完整的消息类型,不需要手动重复定义结构。 - 如果不传入特定Schema,默认使用
BaseMessageBodySchema对应的类型,和原代码的Message<MessageBody>行为一致。
内容的提问来源于stack exchange,提问作者Blee
相关产品推荐
相关产品推荐

