扩展Mongoose Document接口时遭遇TypeScript类型错误求助
解决Mongoose扩展Document和Model时的TypeScript类型错误
我来帮你搞定这两个TypeScript类型问题,顺便提几个容易踩的小坑:
问题1:'model' property does not exist in 'IUserDocument'
这个错误是因为Mongoose的Document类型没有显式暴露model属性的类型定义——虽然运行时能正常调用,但TypeScript编译期识别不到它。我们只需要在自定义的IUserDocument接口里补充这个属性的类型声明就行:
修改users.types.ts中的IUserDocument接口:
import { Document, Model } from 'mongoose' export interface IUser { // 注意:建议用小写基本类型(number/string)代替大写构造函数类型(Number/String) chatId: number, username: string, name?: string, firstName?: string, lastName?: string, age?: number, sex?: string, partner?: string, updatedAt?: Date } export interface IUserDocument extends IUser, Document { setLastUpdated: (this: IUserDocument) => Promise<void> // 补充model属性的类型声明,让TypeScript认识它 model: (modelName: string) => Model<IUserDocument> } export interface IUserModel extends Model<IUserDocument> { findOneOrCreate: ({ chatId, username }: { chatId: number; username: string }) => Promise<IUserDocument> }
另外,你的setUsername方法返回类型写的是Document[],建议改成IUserDocument[],这样能获得更精准的类型提示:
export async function setUsername(this: IUserDocument): Promise<IUserDocument[]> { return this.model("user").find({ username: this.username }) }
问题2:'this' implicitly contains type 'any' in static method
静态方法里的this指向的是Model本身(也就是IUserModel类型),所以必须给this加明确的类型注解,让TypeScript清楚它的类型:
修改users.statics.ts中的findOneOrCreate方法:
import { IUserModel, IUserDocument } from './users.types' // 给this添加IUserModel类型注解,同时修正参数类型(用小写number/string) export async function findOneOrCreate(this: IUserModel, { chatId, username }: { chatId: number; username: string }) { const record = await this.findOne({ chatId, username }) if (record) { return record } else { // 注意:create方法需要传入对象,不是单独参数 return this.create({ chatId, username }) } }
这里还要提个小错误:你原来写的this.create(chatId, username)是不对的,Mongoose的create方法需要传入包含字段的对象,改成this.create({ chatId, username })才能正确创建文档。
最后补充个小细节:TypeScript里尽量用小写的number、string等基本类型,别用大写的Number、String构造函数类型,能避免不少潜在的类型兼容问题。
内容的提问来源于stack exchange,提问作者sfarzoso
相关产品推荐
相关产品推荐

