如何基于传入的Zod Schema获取动态返回值的TypeScript推断类型
解决Zod Schema参数下TypeScript类型推断丢失问题
你的问题出在函数参数的类型定义上——使用z.AnyZodObject作为Schema的类型会抹平具体Schema的类型信息,导致TypeScript无法推断出返回值的精确结构。要解决这个问题,需要用泛型约束来保留传入Schema的类型细节,同时调整返回值的来源确保类型对齐。
修改方案:
将getRandomObject改为泛型函数,通过泛型参数捕获具体的Zod Schema类型,同时返回Schema.parse()的结果(而非原始的obj),因为parse方法会返回经过校验且符合Schema类型的对象,让TypeScript能准确推断结构。
修改后的完整代码:
import { z } from "zod"; const User = z.object({ name: z.string(), age: z.number() }); const randomObjects = [ { name: "Tommy", age: 16 }, { car: "BMW" } ]; // 改用泛型T约束Schema的类型,保留具体Schema的类型信息 export const getRandomObject = <T extends z.ZodType>( Schema: T ): z.infer<T> => { try { const obj = Math.random() > 0.5 ? randomObjects[0] : randomObjects[1]; // 返回parse的结果,而非原始obj,确保类型与Schema对齐 return Schema.parse(obj); } catch (error) { throw new Error("返回对象不符合指定Schema"); } }; const user = getRandomObject(User); // 此时user会被正确推断为{ name: string; age: number; } console.log(user.name, user.age); // TypeScript能识别这两个属性
关键改动说明:
- 泛型参数
T extends z.ZodType:让函数能捕获传入的具体Schema类型(比如这里的User对象对应的Zod类型),而不是用宽泛的AnyZodObject丢失类型信息。 - 返回
Schema.parse(obj):parse方法不仅会校验对象结构,还会返回符合Schema定义的类型值,TypeScript会自动将返回值类型关联到z.infer<T>,从而正确推断出user的结构为{ name: string; age: number; }。
这样修改后,user的类型就能被TypeScript正确识别,同时保留了运行时的Schema校验逻辑。
内容的提问来源于stack exchange,提问作者Mimoid
相关产品推荐
相关产品推荐

