You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 05:10:23