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

TSeD中如何为模型属性声明多类型?JSON转存冲突解决

无需拆分模型,两种优雅解决方案

方案一:用ORM字段转换器自动处理(推荐)

看你的代码用了Typegoose/Mongoose风格的装饰器,直接给content字段加自动转换逻辑就行,ORM会帮你在存库时把对象转成JSON字符串,读库时再转回对象,不用手动在接口里折腾,彻底解决类型不匹配问题。

修改BlogModel:

import { Transform } from 'class-transformer';

export class BlogModel {
  // 其他字段保持不变

  @Property()
  // 存库时:对象转JSON字符串
  @Transform(({ value }) => typeof value === 'object' && value ? JSON.stringify(value) : value, { toPlainOnly: false })
  // 读库时:JSON字符串转对象
  @Transform(({ value }) => typeof value === 'string' ? JSON.parse(value) : value, { toClassOnly: true })
  content: object;
}

然后接口里直接用模型,不用手动转字符串:

@Post("/")
@Summary("Create New Blog")
@Returns(201, BlogModel)
async create(@BodyParams() @Groups("creation") blog: BlogModel): Promise<BlogModel> {
  blog.content = await this.mediaService.contentMediaConvert(blog.content);
  return await this.service.create(blog);
}

这样前端传对象,数据库存字符串,返回给前端还是对象,全程自动处理,代码干净还没类型警告。

方案二:用DTO分离输入输出逻辑

如果不想改模型转换器,就用**数据传输对象(DTO)**把前端输入和数据库存储的结构分开:

  1. 写个CreateBlogDTO专门接收前端数据:
export class CreateBlogDTO {
  @Required()
  @Lowercase()
  title: string;

  @Lowercase()
  slug: string;

  @Any()
  content: object; // 和前端传入的对象类型匹配

  // 其他必填字段:category、createdBy、thumbnail等,跟BlogModel对应上
}
  1. 修改BlogModel的content类型为string(对应数据库存储类型):
export class BlogModel {
  // 其他字段不变

  @Property()
  content: string;
}
  1. 接口里用DTO接收,服务层做转换:
@Post("/")
@Summary("Create New Blog")
@Returns(201, BlogModel)
async create(@BodyParams() @Groups("creation") blogDto: CreateBlogDTO): Promise<BlogModel> {
  const processedContent = await this.mediaService.contentMediaConvert(blogDto.content);
  // 把处理后的对象转成字符串,再转成模型类型存库
  const blogToSave = { ...blogDto, content: JSON.stringify(processedContent) } as BlogModel;
  return await this.service.create(blogToSave);
}

// 查询接口返回时,把字符串转回对象给前端
@Get("/")
@Summary("Return List Of blogs")
@Returns(200, Array)
async getAll(@QueryParams() blogFilter: any) {
  const blogs = await this.service.findMany(blogFilter);
  return blogs.map(blog => ({ ...blog, content: JSON.parse(blog.content) }));
}

这种方式把输入输出和数据库存储解耦,适合需要严格区分数据结构的场景,但代码量比转换器多一点。

没必要拆分Post和Get模型

拆分两个模型会导致大量重复代码,后续改字段要改两处,维护起来麻烦。上面两种方案都能在一套模型(或配合DTO)下解决问题,更省心。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 18:50:26