Mongoose中Schema配置virtuals报错及TypeScript类型问题求助
解决Mongoose + TypeScript虚拟属性的类型问题
问题1:SchemaOptions中virtuals属性不存在的类型错误
Mongoose的JavaScript文档确实支持在SchemaOptions中配置virtuals,但TypeScript的类型定义(Mongoose自带类型或@types/mongoose)并未将virtuals纳入SchemaOptions的类型声明,因此直接编写会触发类型错误。
解决方式:放弃在SchemaOptions中配置,改用Schema.virtual()方法单独定义虚拟属性,这是TypeScript环境下Mongoose推荐的写法。
问题2:虚拟属性在文档实例上的类型不识别
用Schema.virtual()定义后,TypeScript默认不会将虚拟属性纳入文档类型,调用时会提示属性不存在。需通过扩展文档接口解决:
步骤1:定义包含虚拟属性的文档接口
创建继承自业务接口和Mongoose Document的新接口,声明虚拟属性的类型:
import { Document, Schema, Types } from 'mongoose'; // 业务数据接口 interface MyInterface { someProp: Types.ObjectId; myList: Item[]; } // 扩展Document,添加虚拟属性类型 interface MyDocument extends MyInterface, Document { getByType(type: string): Item[]; }
步骤2:创建Schema时指定文档类型
将MyDocument作为泛型参数传入Schema,让Mongoose识别包含虚拟属性的类型:
const mySchema = new Schema<MyDocument>( { someProp: { type: Types.ObjectId, required: true, ref: "some-collection" }, myList: { type: [listSchema], required: true, default: [] }, }, { timestamps: true, toJSON: { virtuals: true }, toObject: { virtuals: true } } );
步骤3:正确定义虚拟属性(注意this指向)
定义虚拟属性时不要用箭头函数(箭头函数会绑定外部上下文,导致this无法指向文档实例),改用普通函数并通过类型注解指定this类型:
mySchema.virtual("getByType").get(function(this: MyDocument, type: string) { return this.myList.filter(item => item.type === type); });
完成以上操作后,调用findOne获取文档实例时,TypeScript就能识别getByType属性,同时也能避免this指向问题。
内容的提问来源于stack exchange,提问作者Marcelino Borges
相关产品推荐
相关产品推荐

