【问题标题】:Mongoose static Model definitions in TypescriptTypescript 中的 Mongoose 静态模型定义
【发布时间】: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 知道模型上存在的方法,而不是模型实例?

【问题讨论】:

    标签: typescript mongoose-schema mongoose-models


    【解决方案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&lt;CampaignModelInterface, CampaignInterface&gt;。这不起作用:model&lt;CampaignInterface, CampaignModelInterface&gt;
    • @Mykola 在类型文件中的model 的definition 是function model&lt;T extends Document, U extends Model&lt;T&gt;&gt;。因此订单是model&lt;CampaignInterface, CampaignModelInterface&gt;(...)。
    猜你喜欢
    • 2021-03-18
    • 2017-07-15
    • 1970-01-01
    • 2019-01-15
    • 2014-09-11
    • 2019-03-18
    • 2019-11-26
    • 2021-11-29
    • 1970-01-01
    相关资源
    最近更新 更多