Typegoose中updateOne钩子使用问题:与save钩子差异及类型兼容
在Typegoose中正确配置updateOne的pre文档中间件
你遇到的问题核心其实是Mongoose中间件的默认行为导致的——updateOne的pre钩子默认绑定到Query对象上,而save钩子绑定到文档实例上,两者的this指向完全不同,类型自然不匹配。
根据你提到的Mongoose文档,要把updateOne的中间件改成文档中间件(让this指向文档实例),需要在注册中间件时加上{ document: true, query: false }的配置选项。在Typegoose里,这个配置可以直接通过@pre装饰器的第二个参数传入,具体修改你的代码如下:
@pre<Question>('updateOne', { document: true, query: false }, function () { debug.log('updating', this) // 现在this的类型就是DocumentType<Question>,和save钩子一致 this.cname = this.cname || makeCname(this.text) this.simple = this.simple || makeCname(this.text) recalcVotes(this) // 这里类型就兼容了 debug.log('cleaned', this) })
补充说明:
为什么升级包后不再报错但类型还是不同?
升级到mongoose@5.11.0和@typegoose/typegoose@7.4.2后,类型定义已经支持了这种配置,但你之前的代码没有传递选项,所以Typegoose仍然推断this是Query类型。只有显式传入{ document: true },Typegoose才会正确把this的类型推断为你的文档类型DocumentType<Question>。关于触发场景的区别:
- 设置
{ document: true, query: false }时,中间件只会在调用文档实例的updateOne方法(比如doc.updateOne())时触发; - 如果需要让
Model.updateOne()也触发中间件,可调整配置为{ query: true },但此时this会回到Query对象,你需要用this.getUpdate()等方法获取更新内容,类型也会不同,根据你的需求选择即可。
- 设置
内容的提问来源于stack exchange,提问作者dcsan
相关产品推荐
相关产品推荐

