Description
The instructions in this repo seem to contradict the main mongoose docs. According to the main docs (https://mongoosejs.com/docs/typescript/virtuals.html#set-virtuals-type-manually) virtuals should be defined after creating the schema:
interface UserDoc {
firstName: string;
lastName: string;
}
interface UserVirtuals {
fullName: string;
}
type UserModel = Model<UserDoc, {}, UserVirtuals>; // <-- add virtuals here...
const schema = new Schema<UserDoc, UserModel, UserVirtuals>({
firstName: String,
lastName: String,
});
schema.virtual('fullName', {
get() {
return `${this.firstName} ${this.lastName}`;
},
});
const UserModel = model('User', schema);
const user = await UserModel.findOne().lean<UserDoc & VirtualsForModel<typeof UserModel>>({ virtuals: true }).orFail();
console.log(user.fullName); // <--- Property 'fullName' does not exist on type 'UserDoc'.ts(2339)
This works well in the sense that there are no errors from defining the virtuals, however the inferred type in VirtualsForModel
aren't correct.
According to the docs in this repo virtuals should instead be defined when creating the schema (https://github.com/mongoosejs/mongoose-lean-virtuals?tab=readme-ov-file#typescript):
const testSchema = new Schema(
{
name: { type: String, required: true },
},
{
virtuals: {
nameUpper: {
get() {
return this.name.toUpperCase();
},
},
},
},
);
However if one needs to define the model interface in the schema (Which is standard practice, just as in the above mongoose docs), this approach no longer works:
interface ITest {
name: string;
}
interface TestVirtuals {
nameUpper: string;
}
type TestModel = Model<ITest, {}, TestVirtuals>;
const testSchema = new Schema<ITest, TestModel, TestVirtuals>(
{
name: { type: String, required: true },
},
{
virtuals: {
nameUpper: {
get() { // <--- 'get' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.ts(7023)
return this.name.toUpperCase(); // <--- Property 'name' does not exist on type '{ get(): any; }'.ts(2339)
},
},
},
},
);
Is there any way to define lean virtuals which is also compatible with defining the interface when creating the schema?