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

如何在Typegoose/Mongoose中实现Timecode自定义类型自动序列化反序列化

该需求完全可以实现,核心通过Mongoose自定义Schema类型 + Typegoose全局类型注册完成,不需要每个使用Timecode的属性单独配置,具体操作步骤如下:


步骤1:实现Mongoose自定义Timecode Schema类型

自定义Schema类型负责处理存库序列化、读库反序列化的逻辑:

import * as mongoose from 'mongoose';
import { Timecode } from './your-timecode-path';

export class TimecodeSchemaType extends mongoose.SchemaType {
  constructor(path: string, options?: any) {
    super(path, options, 'Timecode');
  }

  // 从数据库读取时,自动把存储的字符串转为Timecode实例
  cast(val: any): Timecode {
    if (val instanceof Timecode) return val;
    if (typeof val === 'string') return new Timecode(val);
    throw new Error(`无法将${typeof val}类型的值转换为Timecode实例`);
  }

  // 存入数据库时,自动把Timecode实例转为字符串存储
  toBSON(val: any): string {
    return this.cast(val).toString();
  }

  // 查询时自动把Timecode实例参数转为字符串匹配
  castForQuery(val: any): string {
    return this.toBSON(val);
  }
}

// 注册到Mongoose全局类型列表
mongoose.Schema.Types.Timecode = TimecodeSchemaType;

步骤2:全局注册到Typegoose类型映射

注册后Typegoose会自动识别代码中的Timecode类型,不需要每个属性单独配置Schema类型:

import { registerType } from '@typegoose/typegoose';
import { Timecode } from './your-timecode-path';
import { TimecodeSchemaType } from './your-schema-type-path';

registerType(Timecode, {
  schemaType: TimecodeSchemaType,
  // 可选:配置该类型的默认属性,比如默认是否必填
  defaultOptions: { required: false }
});

注意:请确保上述自定义类型、全局注册的代码,在所有使用Timecode的实体类定义之前执行,避免类型映射失败。


步骤3:业务代码无需修改,直接使用

你原有的Clip实体类可以保持原有写法,不需要额外配置:

import { prop } from '@typegoose/typegoose';

export class Clip extends BaseEntity {
  @prop({ required: true })
  name: string;

  @prop({ required: true })
  description: string;

  // 无需额外配置,Typegoose自动映射为自定义Schema类型
  @prop({ required: true })
  startTimecode: Timecode;
}

效果验证

你的示例代码可以直接正常运行,完全符合预期:

const clip = new Clip();
clip.name = "My Clip"
clip.description = "My Description"
clip.startTimecode = new Timecode("00:00:12:34")  
const savedClip = await ClipModel.create(clip)
// 数据库中startTimecode字段存储为字符串"00:00:12:34"
const loadedClip = await ClipModel.findById(savedClip._id)
// 读库后自动转为Timecode实例,可直接调用类方法
console.log(loadedClip.startTimecode.getAsMilliseconds()) // 正常运行

查询时也可以直接传入Timecode实例,会自动转成字符串匹配:

const targetTime = new Timecode("00:00:12:34");
const clips = await ClipModel.find({ startTimecode: targetTime });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 10:27:04