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

Zod createQuerySchema类型推断异常:缺失条件键与枚举值

解决Zod动态创建QuerySchema时类型推断不准确的问题

问题分析

你编写的createQuerySchema函数期望根据传入的config对象动态生成Zod schema,且通过z.infer得到的类型仅包含实际传入的键,每个键的类型是对应数组值的枚举联合类型。但当前实现中,z.infer得到的类型包含了所有可选键(include和fields)且类型为unknown,这是因为泛型定义没有正确关联返回的Zod对象类型,TS无法准确推断出动态构建的schema结构。

解决方案

通过调整泛型定义,让函数捕获传入config的具体类型,并基于该类型显式指定返回的Zod对象类型,从而让TS能正确推导z.infer的结果。

修改后的完整代码

import { z, ZodObject, ZodRawShape } from "zod";

const createEnumSchema = <const T extends readonly [string, ...string[]]>(values: T) => 
  z.enum(values).optional();

type QueryConfig = Partial<{
  fields: readonly [string, ...string[]];
  include: readonly [string, ...string[]];
}>;

const createQuerySchema = <const C extends QueryConfig>(config: C) => {
  const shape: ZodRawShape = {};
  
  if (config.fields) {
    shape.fields = createEnumSchema(config.fields);
  }
  if (config.include) {
    shape.include = createEnumSchema(config.include);
  }

  return z.object(shape) as ZodObject<{
    [K in keyof C]: C[K] extends readonly [string, ...string[]] 
      ? z.ZodOptional<z.ZodEnum<C[K]>> 
      : never;
  }>;
};

// 测试用例1:仅传入fields
const querySchema = createQuerySchema({
  fields: ["id", "status", "title"],
});
type QueryType = z.infer<typeof querySchema>;
// 类型结果:{ fields?: "id" | "status" | "title" | undefined }

// 测试用例2:仅传入include
const querySchema2 = createQuerySchema({
  include: ["user", "comments"],
});
type QueryType2 = z.infer<typeof querySchema2>;
// 类型结果:{ include?: "user" | "comments" | undefined }

// 测试用例3:同时传入fields和include
const querySchema3 = createQuerySchema({
  fields: ["id", "title"],
  include: ["user"],
});
type QueryType3 = z.infer<typeof querySchema3>;
// 类型结果:{ fields?: "id" | "title" | undefined; include?: "user" | undefined }

关键改动说明

  1. 调整createEnumSchema:添加.optional(),让生成的枚举schema对应可选字段,与config中的可选键匹配。
  2. 单一泛型捕获config类型:用泛型C捕获传入config的具体结构,替代原来分开的F和I,确保能准确获取实际传入的键。
  3. 显式指定返回类型:通过类型断言将z.object(shape)的类型指定为ZodObject,其中每个键对应C中的键,值为对应的可选枚举类型,让TS能正确推导z.infer的结果。

内容的提问来源于stack exchange,提问作者Zorp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.01 13:32:31