14

我创建了一个 Mongoose Schema 并为模型添加了一些静态方法,名为 Campaign。

如果我 console.log Campaign 我可以看到上面的方法。问题是我不知道在哪里添加这些方法,以便 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 知道模型上存在的方法,而不是模型实例?

4

1 回答 1

23

我在这里回答了一个非常相似的问题,尽管我会回答你的问题(主要是我的另一个答案的第三部分),因为你提供了不同的模式。有一个有用的关于 Mongoose 类型的自述文件,它相当隐藏,但是有一个关于静态方法的部分。


您描述的行为是完全正常的 - 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
于 2017-08-14T18:45:01.547 回答