如何在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
相关产品推荐
相关产品推荐

