传递Zod Schema作为函数参数并使用safeParse时的类型问题
问题:DynamoDB响应解析函数的TypeScript/ESLint类型报错
我正在为用于与DynamoDB交互的数据库模块编写一个通用的“解析响应”函数,代码如下:
const parseDynamoResponse = <T extends z.ZodTypeAny>(items: Record<string, unknown>[] | undefined, schema: T) => { if (!items) return []; return items.map((item) => { const validatedItem = schema.safeParse(item); if (validatedItem.success) { return validatedItem.data as z.infer<T>; } logger().warn("item failed validation", validatedItem); return null; }).filter(isNotNullOrUndefined); };
我尝试遵循Zod文档中关于为Schema使用泛型类型参数的实现方式,但即使添加了return validatedItem.data as z.infer<T>这样的类型断言,TypeScript和ESLint仍对该行报错:
ESLint: Unsafe return of type 'any' from function with return type 'TypeOf<T> | null'.(@typescript-eslint/no-unsafe-return)
请问我哪里出错了?
解决方法
问题出在z.ZodTypeAny的泛型约束上——这个类型过于宽泛,涵盖了所有Zod类型,但TypeScript无法从该约束中推断出validatedItem.data的具体类型,因此会将其判定为any,触发ESLint的不安全返回警告。
你可以通过以下两步调整解决问题:
- 收紧泛型约束
将T extends z.ZodTypeAny替换为T extends z.ZodType<z.infer<T>>,让TypeScript明确关联Schema与其推断出的类型,此时无需额外类型断言,TypeScript就能自动识别validatedItem.data的类型:
const parseDynamoResponse = <T extends z.ZodType<z.infer<T>>>(items: Record<string, unknown>[] | undefined, schema: T) => { if (!items) return []; return items.map((item) => { const validatedItem = schema.safeParse(item); if (validatedItem.success) { return validatedItem.data; } logger().warn("item failed validation", validatedItem); return null; }).filter(isNotNullOrUndefined); };
- 优化数组过滤的类型推断
默认情况下,Array.filter(isNotNullOrUndefined)可能无法自动排除数组中的null类型,你可以给类型守卫函数添加明确的类型定义,让TypeScript正确推断过滤后的数组类型:
const isNotNullOrUndefined = <T>(val: T | null | undefined): val is T => { return val !== null && val !== undefined; };
添加该类型定义后,filter处理后的数组会自动被推断为z.infer<T>[]类型。
另外,你之前添加的as z.infer<T>类型断言其实是多余的——当schema.safeParse(item).success为true时,Zod已经能让TypeScript自动识别validatedItem.data为z.infer<T>类型,问题的核心是初始泛型约束过于宽松导致类型推断失效。
内容的提问来源于stack exchange,提问作者DrChoppy
相关产品推荐
相关产品推荐

