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

如何将Prisma查询返回的字符串转换为TypeScript枚举?

Prisma字符串字段与TypeScript枚举类型不匹配的解决方案

方案1:使用Prisma原生枚举类型(推荐)

直接在Prisma Schema中定义枚举,替代单独的TS枚举,生成的客户端类型会自动对齐,查询返回的字段直接是枚举类型,无需额外转换。

修改Prisma Schema:

enum Status {
  OK
  ERROR
}

model User {
  id     String  @id @default(uuid())
  status Status? @db.VarChar(20) // 仍可指定数据库存储类型为VarChar
}

重新生成Prisma客户端:

npx prisma generate

之后直接使用Prisma生成的Status枚举,查询返回的user.status类型自动匹配,无类型错误:

import { Status } from '@prisma/client';

const user = await prisma.user.findFirst({ where: { id: 'uuidhere' } });
return <MyComponent status={user.status} />;

优点:类型完全对齐,无需手动维护TS枚举与数据库字段的一致性,Prisma自动处理映射。
缺点:若使用MySQL等数据库,原生枚举会绑定数据库枚举,修改枚举值需执行数据库迁移。


方案2:通过TypeScript模块扩充覆盖Prisma类型

若不想修改数据库枚举类型,可通过TS模块扩充,将Prisma生成的User类型中的status字段替换为自定义Status枚举,实现类型层面对齐。

步骤:

  1. 保留原有TS枚举定义:
export enum Status {
  OK = 'ok',
  ERROR = 'error',
}
  1. 创建类型扩充文件(如prisma-types.d.ts):
import { Prisma } from '@prisma/client';
import { Status } from './your-enum-file';

declare module '@prisma/client' {
  interface User {
    status?: Status;
  }

  // 扩充客户端操作类型,确保写入时也支持枚举
  interface PrismaClient {
    user: Omit<Prisma.UserDelegate, 'create' | 'update' | 'updateMany'> & {
      create: Prisma.UserCreateDelegate<{ status?: Status }>;
      update: Prisma.UserUpdateDelegate<{ status?: Status }>;
      updateMany: Prisma.UserUpdateManyDelegate<{ status?: Status }>;
    };
  }
}

此后所有查询返回的User对象的status字段,都会被TS识别为Status枚举,无需手动转换或断言。

优点:无需修改数据库或Prisma Schema,仅通过类型层面解决问题。
缺点:需维护类型扩充代码,若Prisma Schema变更需同步更新扩充逻辑。


方案3:使用Prisma中间件自动转换并验证

通过Prisma中间件,在查询返回结果时自动将字符串转为Status枚举,同时验证值的合法性,避免无效值流入业务代码。

实现中间件:

import { PrismaClient } from '@prisma/client';
import { Status } from './your-enum-file';

const prisma = new PrismaClient();

// 验证字符串是否为合法Status枚举值
const isValidStatus = (value: string): value is Status => {
  return Object.values(Status).includes(value as Status);
};

prisma.$use(async (params, next) => {
  const result = await next(params);

  // 处理User模型的查询结果
  if (params.model === 'User' && ['findUnique', 'findFirst', 'findMany'].includes(params.action)) {
    const transformStatus = (data: any) => {
      if (data?.status && isValidStatus(data.status)) {
        data.status = Status[data.status as keyof typeof Status];
      }
      return data;
    };

    // 兼容单条数据和数组结果
    return Array.isArray(result) ? result.map(transformStatus) : transformStatus(result);
  }

  return result;
});

配合方案2的类型扩充,可实现运行时自动转换+类型系统对齐,完全无需手动处理转换逻辑。

优点:自动处理所有查询结果,同时验证枚举值合法性,避免无效数据。
缺点:存在轻微运行时性能开销(可忽略),需维护中间件逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 12:45:17