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

Prisma+Node.js项目Decimal与number类型不兼容报错解决方案求助

报错根因

该报错和循环依赖完全无关,核心是类型不匹配:

  • 你使用的2.28.0版本Prisma Client,默认会将PostgreSQL数据源的Float类型字段映射为Decimal.js的Decimal实例,而非JS原生number类型
  • 你自定义的Finance、VaultTransaction等TS类型文件中,将gold、vaultGold、amount等数值字段声明为了number类型,二者类型不匹配触发TS编译报错
解决方案

你可以根据业务场景任选以下一种方案处理:

方案1:修改Prisma Client生成配置(推荐,改动最小)

在你的Prisma Schema的generator client配置块中添加decimal = "number"参数,指定所有Decimal类型直接映射为原生JS数字:

generator client {
  provider = "prisma-client-js"
  decimal = "number"
}

修改完成后执行npx prisma generate重新生成Prisma Client即可,无需改动其他业务代码。

方案2:对齐自定义类型声明

将你自行编写的模型TypeScript类型中,对应数值字段的类型从number修改为Decimal(引入Prisma Client导出的Decimal类型即可),在业务代码中需要做数值运算时,调用.toNumber()方法转为原生数字使用。

方案3:Service层手动转换

在查询返回结果后手动遍历将Decimal字段转为number,以你提供的FinanceService为例修改如下:

import { Decimal } from '@prisma/client/runtime'

@Injectable()
export class FinanceService {
  async getFinances(): Promise<Finance[]> {
    const rawFinances = await prisma.finance.findMany({
      include: {
        transactions: true,
      },
    });
    // 手动转换所有Decimal字段为number
    return rawFinances.map(finance => ({
      ...finance,
      gold: (finance.gold as Decimal).toNumber(),
      vaultGold: (finance.vaultGold as Decimal).toNumber(),
      transactions: finance.transactions.map(tx => ({
        ...tx,
        amount: (tx.amount as Decimal).toNumber()
      }))
    }))
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 09:09:05