Zod中.strict()包装函数类型断裂:如何实现无临时方案的条件严格校验?
解决Zod条件严格校验的类型问题
你遇到的类型问题根源在于:schema.strict()返回的是一个新的ZodObject实例,其类型与原schema(泛型T)并不完全一致——原T的未知键处理模式(比如strip或passthrough)会被strict()修改为strict模式,因此直接用as T断言是不准确的,只是强行绕过了TypeScript的类型检查。
正确实现方式
我们可以通过精确的泛型定义,让函数返回的类型明确为「原schema」或「其strict版本」,同时保证两者的输出类型一致,无需临时类型断言:
import { z } from 'zod'; const strictIfTesting = < Shape extends z.ZodRawShape, UnknownKeys extends z.UnknownKeysParam, Catchall extends z.ZodTypeAny >(schema: z.ZodObject<Shape, UnknownKeys, Catchall>) => { const isProductionEnvironment = "window" in globalThis; return isProductionEnvironment ? schema : schema.strict(); };
类型推导说明
- 泛型
Shape、UnknownKeys、Catchall分别对应ZodObject的三个核心类型参数:对象结构、未知键处理策略、兜底类型。 schema.strict()返回的类型是z.ZodObject<Shape, 'strict', Catchall>,与原schema的类型(z.ZodObject<Shape, UnknownKeys, Catchall>)形成联合类型,但两者的z.infer<>输出类型完全一致(都是Shape对应的类型),因此调用parse时TypeScript会正确推导返回值类型,不会出现unknown问题。
简化版实现
如果不需要过于精细的泛型控制,也可以利用z.ZodType<z.infer<T>>来统一返回类型,确保输出类型一致:
import { z } from 'zod'; const strictIfTesting = <T extends z.ZodObject<any, any, any>>(schema: T): z.ZodType<z.infer<T>> => { const isProductionEnvironment = "window" in globalThis; return isProductionEnvironment ? schema : schema.strict(); };
这个版本更简洁,核心思路是告诉TypeScript:无论返回原schema还是strict版本,最终解析出的类型都是原schema对应的输出类型z.infer<T>。
内容的提问来源于stack exchange,提问作者RareScrap
相关产品推荐
相关产品推荐

