部署时报错:Type 'string' is not assignable to type 'never'(Prisma 关联字段问题)


项目在本地开发和测试环境均正常,但在部署时,应用启动失败,日志报错:

bash 复制代码
src/devices/devices.service.ts:14:7 - error TS2322: Type 'string' is not assignable to type 'never'.

报错位置为:

ts 复制代码
// devices.service.ts
return this.prisma.device.create({
   createDeviceDto, // 报错指向这一行
});

经过

检查代码发现,CreateDeviceDto 中定义了 deviceGroupId 字段:

ts 复制代码
// create-device.dto.ts
export class CreateDeviceDto {
  @IsString()
  name: string;

  @IsIP()
  ipAddress: string;

  @IsUUID()
  @IsOptional()
  deviceGroupId?: string; // 类型为 string
}

对应的 Prisma 模型为:

prisma 复制代码
model Device {
  id              String
  name            String
  deviceGroupId   String?
  deviceGroup     DeviceGroup? @relation(fields: [deviceGroupId], references: [id])
}

查看 Prisma 生成的类型定义:

ts 复制代码
// node_modules/.prisma/client/index.d.ts
export type DeviceCreateInput = {
  name: string;
  ipAddress: string;
  deviceGroupId?: never; // 注意:类型是 never
  deviceGroup?: { connect: { id: string } };
};

原因定位

Prisma 在 6.x 版本中,对于通过 @relation(fields: [...]) 定义的外键字段,在创建输入类型中将其标为 never,防止直接赋值。必须通过关系字段 deviceGroup.connect 的方式建立关联。


处理方案

方案一:修改 DTO,使用关系字段(推荐)

ts 复制代码
export class CreateDeviceDto {
  @IsString()
  name: string;

  @IsIP()
  ipAddress: string;

  @ValidateNested()
  @Type(() => DeviceGroupConnectDto)
  @IsOptional()
  deviceGroup?: { connect: { id: string } };
}

class DeviceGroupConnectDto {
  @IsString()
  @IsUUID()
  id: string;
}

前端传参格式:

json 复制代码
{
  "name": "web-server",
  "ipAddress": "192.168.1.10",
  "deviceGroup": {
    "connect": {
      "id": "cmg_abc123"
    }
  }
}

Service 层直接透传:

ts 复制代码
return this.prisma.device.create({
   createDeviceDto,
});

方案二:保持 DTO 不变,在 Service 中转换

ts 复制代码
const { deviceGroupId, ...rest } = createDeviceDto;
return this.prisma.device.create({
   {
    ...rest,
    deviceGroup: deviceGroupId ? { connect: { id: deviceGroupId } } : undefined,
  }
});

最终选择

项目为新系统,MVP 刚完成,前端尚未正式对接,无历史兼容压力

因此,选择方案一:修改 DTO,使用 deviceGroup.connect 模式

选择理由

  • 符合 Prisma 推荐的最佳实践
  • 类型系统完全对齐,避免后续类似问题
  • 为后续支持 createconnectOrCreate 等操作预留扩展性
  • 从一开始就建立统一的关联处理规范,利于团队协作

结果

重新部署后,TypeScript 编译通过,应用正常启动,设备创建功能验证无误。

后续其他模块的关联字段均按此模式统一处理。


#Prisma #NestJS #TypeScript #Deployment #TypeNever #TypeError #数据库关联

相关推荐
倾颜18 小时前
NestJS 核心概念梳理:从 Module、Controller 到 Guard、Interceptor
后端·node.js·nestjs
薛定谔的算法1 天前
NestJS:让 Node.js 后端告别「野路子」
后端·node.js·nestjs
To_OC4 天前
从一行入口代码啃透 NestJS:工厂模式、装饰器和依赖注入是怎么串起来的
后端·设计模式·nestjs
__zRainy__5 天前
Node.js Web 框架选型指南:从 Express 到 Hono 的全景对比
前端·node.js·express·koa·nestjs·egg·fastify
Darling噜啦啦5 天前
NestJS 全栈 CRUD 实战:从 Module 拆分到 RESTful 七大装饰器,彻底搞懂后端接口工程
nestjs
嘟嘟07175 天前
从入口到 CRUD:用 NestJS 的模块化与装饰器思想读懂一个后端应用
后端·typescript·nestjs
想要成为糕糕手5 天前
🚀 NestJS 完全入门指南: Module/Controller/Service讲解 + 实战 CRUD
后端·nestjs
想要成为糕糕手5 天前
🏭 设计模式之工厂模式:从蜜雪冰城到 NestJS,把「new」外包出去
后端·nestjs
小月土星5 天前
用设计哲学的眼光重新审视 NestJS——一个 AI 应用后端的思考
nestjs