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

如何缩小Prisma查询返回的type字段类型范围?

问题:Prisma连接MSSQL时,如何将String类型字段收窄为自定义联合类型?

我有如下Prisma Schema:

model Example {
    id        String   @id @default(cuid())
    createdOn DateTime @default(now())
    type      String
}

type字段只能取以下值之一:

const Types = [
  "createdLicense",
  "archivedLicense",
  "updateProcessingType",
  ...
] as const;
type HistoryType = (typeof Types)[number];

因为使用Prisma连接MSSQL数据库,无法使用Prisma的枚举类型。插入数据时,我通过satisfies运算符确保type字段无拼写错误:

type: "archivedLicense" satisfies HistoryType,

这种方式插入时没问题,但查询时存在问题:返回的type字段类型为string,范围过宽。我尝试扩展Prisma客户端,但当前方案无效:

const custom = prisma.$extends({
  name: "example",
  query: {
    example: {
      async findMany({ model, args, operation, query }) {
        const queryResult = await query(args);
        return queryResult.map((item) => {
          return {
            ...item,
            type: item.type as HistoryType,
          };
        });
      },
    },
  },
});

执行后返回的type类型仍然是string。


解决方案

1. 使用Prisma扩展的result钩子收窄类型

要同时在类型系统和运行时实现字段类型收窄,应该使用Prisma扩展的result字段,而非query钩子。result会直接修改Prisma生成的类型定义,同时可以添加运行时校验确保数据合法性:

const Types = [
  "createdLicense",
  "archivedLicense",
  "updateProcessingType",
  ...
] as const;
type HistoryType = (typeof Types)[number];

// 运行时校验函数,确保返回的type属于允许的集合
const isHistoryType = (value: unknown): value is HistoryType => {
  return typeof value === 'string' && (Types as readonly string[]).includes(value);
};

const customPrisma = prisma.$extends({
  result: {
    example: {
      type: {
        needs: { type: true }, // 声明需要获取原始的type字段值
        compute(item) {
          const rawType = item.type;
          if (!isHistoryType(rawType)) {
            throw new Error(`无效的type值:${rawType}`);
          }
          return rawType;
        },
      },
    },
  },
});

2. 为什么之前的query方案无效?

之前的query钩子只是在运行时修改了返回值,但TypeScript仍然沿用Prisma Client生成的原始类型定义,所以编译时和IDE中type还是显示为string。而result扩展会直接更新Prisma的类型系统,让type字段的类型被正确收窄为HistoryType。

3. 优势:自动覆盖所有查询操作

result扩展会自动应用到所有返回Example模型的查询(比如findUnique、findFirst、findMany、update返回值等),不需要为每个查询操作单独编写钩子,更高效。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 15:52:33