如何从Zod Schema自动推断Action类构造函数的泛型类型?
问题描述
我用Zod对不受控的用户输入做Schema校验,定义了以下Schema:
const SchemaValue = z.object({ translatedValue: z.string().or(z.number()) }); const SchemaInput = z.object({ truncate: z.number() });
接着我写了一个简单的Action类,用来执行校验并把类型推断传递给validator方法:
interface ActionOptions<I, V> { name: string; inputSchema: z.AnyZodObject; valueSchema: z.AnyZodObject; validator: (input: I, value: V) => Promise<[string | null, boolean]>; } export class Action<I, V> { options: ActionOptions<I, V>; constructor(options: ActionOptions<I, V>) { this.options = options; } async run(value: V, input: I): Promise<void> { // 额外校验逻辑 await this.options.validator( input, value, ); } }
现在我是这样实例化Action的:
const action = new Action<z.infer<typeof SchemaInput>, z.infer<typeof SchemaValue>>({ inputSchema: SchemaInput, valueSchema: SchemaValue, name: 'someAction', async validator(input, value) { return [null, true]; } });
这段代码能正常运行,validator的参数也有正确的智能提示,但我想简化Action的使用,不用手动传入泛型类型。能不能从inputSchema和valueSchema自动推断出I和V的类型,不用在实例化时手动指定?
解决方案
当然可以实现自动类型推断,只需要调整Action类的泛型定义,让它从传入的Schema中直接推导类型即可。
修改后的Action类代码如下:
import { z, ZodObject } from 'zod'; interface ActionOptions<InputSchema extends ZodObject<any>, ValueSchema extends ZodObject<any>> { name: string; inputSchema: InputSchema; valueSchema: ValueSchema; validator: ( input: z.infer<InputSchema>, value: z.infer<ValueSchema> ) => Promise<[string | null, boolean]>; } export class Action<InputSchema extends ZodObject<any>, ValueSchema extends ZodObject<any>> { options: ActionOptions<InputSchema, ValueSchema>; constructor(options: ActionOptions<InputSchema, ValueSchema>) { this.options = options; } async run( value: z.infer<ValueSchema>, input: z.infer<InputSchema> ): Promise<void> { // 额外校验逻辑 await this.options.validator(input, value); } }
现在实例化Action时,无需手动传入泛型,TypeScript会自动从传入的Schema实例推断出对应的参数类型:
const action = new Action({ inputSchema: SchemaInput, valueSchema: SchemaValue, name: 'someAction', async validator(input, value) { // input自动推断为 { truncate: number } // value自动推断为 { translatedValue: string | number } return [null, true]; } });
核心改动说明
- 将Action和ActionOptions的泛型参数从
I、V改为InputSchema、ValueSchema,并约束它们必须是ZodObject类型 - 在
validator和run方法中,通过z.infer<InputSchema>、z.infer<ValueSchema>自动提取Schema对应的类型 - 借助TypeScript的类型推导能力,从传入的具体Schema实例自动生成参数类型,无需手动指定泛型
内容的提问来源于stack exchange,提问作者Shannon Hochkins
相关产品推荐
相关产品推荐

