如何在definePlugin函数中重写接口并确保返回类型正确?
问题
我定义了一个definePlugin函数,它接受实现PluginConfig接口的对象,默认使用EmailValidator验证器。我尝试重写该接口,提供自定义验证器,同时确保返回值拥有正确的类型,但当前实现中返回的test和test2均为any类型。以下是我的代码:
import { z } from 'zod' // Create de default validator export const EmailValidator = z.object({ email: z .string({ required_error: 'auth.validation.email' }) .email({ message: 'auth.validation.email_format' }) }) // The default interface the generic should at least implement interface PluginConfig { validator?: z.ZodType } // The default interface with the default validator to use if not overriden interface DefaultPluginConfig { validator?: typeof EmailValidator } const definePlugin = <T extends PluginConfig = DefaultPluginConfig>({ validator = EmailValidator }: T) => { return validator.parse({}) } const test = definePlugin({}) // Object should look like EmailValidator but is any instead test.email // Create a custom validator const CustomValidator = z.object({ email: z.string(), username: z.string() }) // Create a custom interface to use as generic interface CustomConfig { validator?: typeof CustomValidator } const test2 = definePlugin<CustomConfig>({ validator: CustomValidator }) // Object should look like CustomValidator but is any instead test2.username test2.username
请问需要做哪些修改,才能让definePlugin在使用自定义验证器时拥有正确的类型?
解决方案
问题核心在于当前泛型仅约束了参数结构,无法让TypeScript精准推导验证器的输出类型。可以通过以下修改解决:
关键调整点
- 直接将泛型绑定到验证器的类型,去掉冗余的接口定义,让TypeScript能直接关联验证器与返回值类型
- 优化默认值的类型断言,确保默认场景下的类型推导正确
修改后的完整代码
import { z, ZodType } from 'zod' // 默认验证器 export const EmailValidator = z.object({ email: z .string({ required_error: 'auth.validation.email' }) .email({ message: 'auth.validation.email_format' }) }) // 泛型T代表验证器类型,默认值设为EmailValidator的类型 const definePlugin = <T extends ZodType = typeof EmailValidator>({ validator = EmailValidator as T }: { validator?: T } = {}) => { return validator.parse({}) } // 默认调用:test类型为EmailValidator解析后的对象 const test = definePlugin({}) test.email // 类型正确,不再是any // 自定义验证器 const CustomValidator = z.object({ email: z.string(), username: z.string() }) // 使用自定义验证器:TypeScript自动推导test2类型 const test2 = definePlugin({ validator: CustomValidator }) test2.username // 类型正确,不再是any
说明
- 移除了
PluginConfig和DefaultPluginConfig接口,直接用泛型T约束ZodType,简化类型逻辑 - 参数对象定义为
{ validator?: T }并设置默认空对象,配合EmailValidator as T的类型断言,确保默认调用时类型推导无误 - 无需手动指定泛型,TypeScript会根据传入的
validator自动推导返回值类型
内容的提问来源于stack exchange,提问作者andre de waard
相关产品推荐
相关产品推荐

