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

使用Zod Schema实现工厂模式时遇到类型推断问题

解决Zod工厂模式中的类型推断问题

问题出在你当前的泛型定义上:你只约束了schemas的键名类型T,但把schemas的值宽泛地定义为z.ZodSchema,这会让TypeScript丢失每个具体Schema的类型细节,导致filter无法被正确推断。

修改方案是让泛型直接约束整个schemas对象的类型,保留每个Schema的具体结构:

import { z } from 'zod';

export const makeClient = <S extends Record<string, z.ZodSchema>>({
  schemas,
}: {
  schemas: S;
}) => {
  return {
    async findOne<K extends keyof S>({
      name,
      filter,
    }: {
      name: K;
      filter: z.infer<S[K]>;
    }) {
      return { name, filter };
    },
  };
};

// 使用示例
const client = makeClient({
  schemas: {
    test: z.object({
      value: z.number(),
    }),
    user: z.object({
      id: z.string(),
      email: z.string().email(),
    }),
  },
});

// 现在filter会自动推断对应Schema的类型
client.findOne({
  name: "test",
  filter: {
    value: 123, // 类型推断为number,错误类型会触发TS报错
  }
});

client.findOne({
  name: "user",
  filter: {
    id: "u_123",
    email: "user@example.com"
  }
});

为什么这样改能生效?

  • 泛型S会完整保留传入的schemas对象的结构,包括每个键对应的具体Zod Schema类型,而不是把所有值都统一为宽泛的z.ZodSchema。
  • 调用findOne时,指定name为某个键K后,z.infer<S[K]>可以准确提取该Schema对应的TS类型,TypeScript就能自动提示filter的结构并做类型校验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 07:26:10