Mongoose & TypeScript

1 day ago 2
ARTICLE AD BOX

Question

I am using Mongoose 9.2.2 with TypeScript 5.9.3, and I have a schema that includes:

timestamps: true a virtual populate defined via SchemaOptions.virtuals statics defined inside SchemaOptions.statics

When I call a static method, TypeScript reports a this context type incompatibility, even though the code works fine at runtime.

Minimal Reproducible Example

import mongoose from 'mongoose'; const issueOneSchema = new mongoose.Schema( { placeholder: String }, { timestamps: true, virtuals: { votes: { options: { ref: 'IssueTwo', localField: '_id', foreignField: 'issueOneId' } } }, statics: { myStaticMethod: function () { console.log('placeholder'); } } } ); const IssueOne = mongoose.model('IssueOne', issueOneSchema); IssueOne.myStaticMethod();

TypeScript Error

The 'this' context of type 'Model< { placeholder?: unknown } & DefaultTimestampProps, {}, {}, { votes: unknown } & { id: string }, Document< unknown, {}, { placeholder?: unknown } & DefaultTimestampProps, { votes: unknown } & { id: string } > >' is not assignable to method's 'this' of type 'Model< { placeholder?: string | null | undefined }, {}, {}, { votes: unknown }, Document< unknown, {}, { placeholder?: string | null | undefined }, { votes: unknown } & { id: string }, DefaultSchemaOptions > >'. The types of 'castObject(...).placeholder' are incompatible between these types. Type 'unknown' is not assignable to type 'string | null | undefined'.

What I Tried

Defining the virtual via schema.virtual() instead of SchemaOptions.virtuals works. Removing timestamps: true also fixes the typing. But I want to keep both timestamps and virtual populate, and have properly typed static methods.

Question

Is there a TypeScript-friendly workaround to correctly type this in Mongoose static methods while keeping timestamps and virtual populate?

Any solution, snippet, or best practice would be very helpful!

Read Entire Article