I am trying to learn how to use virtuals with mongoose and typescript.
Say I have an interface for a user.
interface User {
id: mongoose.ObjectId;
name: string;
likes: string;
}
Then I create a schema for mongoose.
// create the model
const user: mongoose.SchemaDefinition<User> = {
name: { type: String },
likes: { type: String },
};
// enable the use of virtuals
const options: mongoose.SchemaOptions = {
toJSON: { getters: true, virtuals: true },
toObject: { virtuals: true },
};
// create the scheme
const schema = new Schema(user, options);
Then I go to add a virtual and create my model.
// attach the virtual "bio" to return a string about the user
schema.virtual("bio").get(function (): string {
return `Hi my name is ${this.name} and i like ${this.likes}`;
});
const model = mongoose.model("User", schema);
However, creating the virtual like above produces this error on this. See below picture.
So I thought that I could modify my virtual based on this post.
schema.virtual("bio").get(function (this: User): string {
return `Hi my name is ${this.name} and i like ${this.likes}`;
});
const model = mongoose.model("User", schema);
However this does not work for me because my theory is that the following is set in my tsconfig "noUnusedLocals": true. I don't wan't to disable this because its a helpful linting rule. See below picture.
So my question is how can I create a mongoose virtual in typescript that does not throw an error like this, is there a simple example somewhere that I have missed while googling?
I guess one solution is to add // eslint-disable-next-line no-unused-vars to the line above to suppress the warning. However that does not explain why this is "unused". Even though it is.
I have even tried specifically using this by setting it to temporary variables (which get IntelliSense for the User interface, so its not like its ignoring the typing).
schema.virtual("bio").get(function (this: IUserModel): string {
const name = this.name;
const like = this.likes;
return `Hi my name is ${name} and i like ${like}`;
});
Here's my full example as one copy-paste-friendly blob.
interface User {
id: mongoose.ObjectId;
name: string;
likes: string;
}
const user: mongoose.SchemaDefinition<User> = {
name: { type: String },
likes: { type: String },
};
const options: mongoose.SchemaOptions = {
toJSON: { getters: true, virtuals: true },
toObject: { virtuals: true },
};
const schema = new Schema(user, options);
// this is defined but never used :(
schema.virtual("bio").get(function (this: User): string {
return `Hi my name is ${this.name} and i like ${this.likes}`;
});
const model = mongoose.model("User", schema);
export default model;

