我有一个definePlugin函数,它接受一个实现PluginConfig接口(interface)的对象,并带有默认的RequestValidator。我正在尝试重写此接口(interface),提供自定义验证器,同时确保返回值具有正确的类型。但是,我当前的实现导致返回的 vueAuth 类型为 any。如何在保持正确的返回类型的同时重写接口(interface)? 这是我当前的代码:
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 具有正确的类型?
最佳答案
您的代码中存在一些导致问题的问题:
您已将
PluginConfig
定义为属性z.ZodType
,它是类型而不是值。您可以修改为:接口(interface)插件配置{ 验证器?:z.Schema; }
在您的代码中,您的
DefaultPluginConfig
接口(interface)未正确扩展PluginConfig
。您可以将其更改为:接口(interface) DefaultPluginConfig 扩展了 PluginConfig { 验证器?:EmailValidator 类型; }
您的代码如下所示:
import { z } from 'zod';
// Create the 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.Schema<any>;
}
// The default interface with the default validator to use if not overridden
interface DefaultPluginConfig extends PluginConfig {
validator?: typeof EmailValidator;
}
const definePlugin = <T extends PluginConfig = DefaultPluginConfig>({
validator = EmailValidator,
}: T) => {
return validator.parse({});
};
const test = definePlugin({});
test.email; // Object has the correct type EmailValidator
// Create a custom validator
const CustomValidator = z.object({
email: z.string(),
username: z.string(),
});
// Create a custom interface to use as generic
interface CustomConfig extends PluginConfig {
validator?: typeof CustomValidator;
}
const test2 = definePlugin<CustomConfig>({
validator: CustomValidator,
});
test2.username; // Object has the correct type CustomValidator
test2.email; // Object has the correct type CustomValidator (from CustomValidator)
如果您仍然遇到任何问题,请告诉我。
更新代码(最终):
根据聊天讨论,正确答案是:
import { z, ZodType } from "zod";
// Create the default validator
export const EmailValidator = z.object({
email: z.string().default("")
});
// The default interface the generic should at least implement
interface PluginConfig<T extends ZodType = typeof EmailValidator> {
validator?: T;
}
const definePlugin = <
T extends PluginConfig = PluginConfig<typeof EmailValidator>,
R = T extends PluginConfig<infer V> ? V : ZodType
>({
validator = EmailValidator
}: T): R extends ZodType<infer P> ? P : never => {
return validator.parse({}) as any;
};
const test = definePlugin({});
test.email; // Object has the correct type EmailValidator
const CustomValidator = z.object({
email: z.string().default(""),
username: z.string().default("")
});
type CustomConfig = PluginConfig<typeof CustomValidator>;
const test2 = definePlugin<CustomConfig>({
validator: CustomValidator
});
console.log(test2.username);
所以这里Generic V和P分别用于从PluginConfig
和ZodType
捕获类型。
这里,
V
- 表示 PluginConfig 中验证器属性的推断类型
P
- 表示 ZodType 的推断类型
这些泛型 V
和 P
允许函数处理不同的验证器配置并基于它返回合适的推断类型。
关于javascript - 如何重写函数中的接口(interface)并保持正确的返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76430738/