Mongoose statiske Modell-definisjoner i Typescript


Jeg opprettet et Mongoose-skjema og la til noen statiske metoder for modellen, kalt Campaign.

Hvis jeg gjør console.log på Campaign, kan jeg se metodene som finnes på den. Problemet er at jeg ikke vet hvor jeg skal legge til disse metodene slik at Typescript også er klar over dem.

Hvis jeg legger dem til i CampaignModelInterface, er de bare tilgjengelige for instanser av modellen (eller i det minste tror TS det).

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

Jeg prøvde også å få tilgang til det via Campaign.schema.statics, men uten hell.

Kan noen gi råd om hvordan man får TS til å vite om metodene som finnes på Modellen, ikke modellinstansene?

Svar #1

Jeg svarte på et veldig lignende spørsmål her, selv om jeg vil svare på ditt (for det meste med den tredje delen av mitt andre svar) siden du har gitt et annet skjema. Det finnes en nyttig readme med Mongoose-typene som er ganske skjult, men det er en seksjon om statiske metoder.

Atferden du beskrev er helt normal - Typescript blir fortalt at Skjemaet (objektet som beskriver individuelle dokumenter) har metoden kalt getLiveCampaigns.

I stedet må du fortelle Typescript at metoden er på modellen, ikke på skjemaet. Når det er gjort, kan du få tilgang til statiske metoder som vanlig i Mongoose. Du kan gjøre det på følgende måte:

// 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

Relaterte artikler