Typescript 中的 Mongoose 静态模型定义
Posted
技术标签:
【中文标题】Typescript 中的 Mongoose 静态模型定义【英文标题】:Mongoose static Model definitions in Typescript 【发布时间】:2018-01-18 17:31:25 【问题描述】:我创建了一个 Mongoose Schema 并为模型添加了一些静态方法,命名为 Campaign。
如果我 console.log 活动,我可以看到上面存在的方法。问题是我不知道在哪里添加这些方法,以便 Typescript 也知道它们。
如果我将它们添加到我的 CampaignModelInterface,它们仅可用于模型实例(或者至少 TS 认为它们是可用的)。
campaignSchema.ts
export interface CampaignModelInterface extends CampaignInterface, Document
// will only show on model instance
export const CampaignSchema = new Schema(
title: type: String, required: true ,
titleId: type: String, required: true
...etc
)
CampaignSchema.statics.getLiveCampaigns = Promise.method(function ()
const now: Date = new Date()
return this.find(
$and: [startDate: $lte: now , endDate: $gte: now ]
).exec()
)
const Campaign = mongoose.model<CampaignModelInterface>('Campaign', CampaignSchema)
export default Campaign
我也尝试通过 Campaign.schema.statics 访问它,但没有运气。
谁能建议如何让 TS 知道模型上存在的方法,而不是模型实例?
【问题讨论】:
【参考方案1】:我在here 上回答了一个非常相似的问题,尽管我会回答你的问题(主要是在我的另一个答案的第三部分),因为你提供了不同的架构。有一个有用的关于 Mongoose 类型的自述文件,它相当隐蔽,但在 static methods 上有一个部分。
您描述的行为完全正常 - Typescript 被告知 Schema(描述单个文档的对象)具有称为 getLiveCampaigns
的方法。
相反,您需要告诉 Typescript 该方法在模型上,而不是模式上。完成后,您可以按照正常的 Mongoose 方法访问静态方法。您可以通过以下方式做到这一点:
// CampaignDocumentInterface should contain your schema interface,
// and should extend Document from mongoose.
export interface CampaignInterface extends CampaignDocumentInterface
// declare any instance methods here
// Model is from mongoose.Model
interface CampaignModelInterface extends Model<CampaignInterface>
// declare any static methods here
getLiveCampaigns(): any; // this should be changed to the correct return type if possible.
export const CampaignSchema = new Schema(
title: type: String, required: true ,
titleId: type: String, required: true
// ...etc
)
CampaignSchema.statics.getLiveCampaigns = Promise.method(function ()
const now: Date = new Date()
return this.find(
$and: [startDate: $lte: now , endDate: $gte: now ]
).exec()
)
// Note the type on the variable, and the two type arguments (instead of one).
const Campaign: CampaignModelInterface = mongoose.model<CampaignInterface, CampaignModelInterface>('Campaign', CampaignSchema)
export default Campaign
【讨论】:
谢谢!很惊讶我之前没有遇到过你的原始答案:) 正如你所建议的那样,能够让它工作。如果我理解正确,我现在会将所有 Schema.static 方法放在 CampaignModelInterface 上,并将所有 Schema.method 方法放在 CampaignDocumentInterface 上? 好吧,我个人将其设置为CampaignDocumentInterface
仅包含架构(如 CampaignSchema
中定义的那样)。 CampaignInterface
包含你所有的 Schema.method
方法,CampaignModelInterface
包含你所有的 Schema.static
方法。
您也可以在CampaignDocumentInterface
中声明您的Schema.method
方法,我个人只是更喜欢分离。
确保您放弃订单:model<CampaignModelInterface, CampaignInterface>
。这不起作用:model<CampaignInterface, CampaignModelInterface>
@Mykola 在类型文件中的model
的definition 是function model<T extends Document, U extends Model<T>>
。因此订单是model<CampaignInterface, CampaignModelInterface>(...)
。以上是关于Typescript 中的 Mongoose 静态模型定义的主要内容,如果未能解决你的问题,请参考以下文章
带有 typescript 和 mongoose 的静态方法会:“一个接口只能扩展一个类或另一个接口。”
Typescript Mongoose - 方法/静态函数未被调用 [Kubernetes - Docker]