Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoose virtuals with typescript error - The containing arrow function captures the global value of 'this' which implicitly has type 'any'

I am trying to use mongoose virtuals with typescript. And not able to make it work. I get error related to using this in the code. I checked many references but could not find a reference to make this work.

"[ts] The containing arrow function captures the global value of 'this' which implicitly has type 'any'. [7041]"

export const UserSchema = new Schema({
    firstName: {
        type: String
    },
    lastName: {
        type: String
    },
    roleId: {
        alias: "group",
        type: String
    }
}, {
    toJSON: {
        transform: (doc, ret, options) => {
            delete ret.id ;
            delete ret.roleId ;
            return ret ;
        },
        virtuals: true,
    }
});

UserSchema.virtual("username").get(() => {
    return this.firstName + " " + this.lastName ;
}) ;

I am expecting a new property "username" which combines values of "firstName lastName"

Alternative code but same error -

UserSchema.virtual("username").get(function() {
    return this.firstName + " " + this.lastName ;
}) ;
like image 345
Dhaval Chokshi Avatar asked Jan 30 '19 16:01

Dhaval Chokshi


2 Answers

Arrow functions by definition capture this from the declaration context. Since you are defining the function directly in the module this will be the global object.

You want to a regular function. A regular function, when called on an object will have this passed into it as the actual object it was called on.

You also need to add a type annotation for this (depeding on your strict settings but you mention you tried a regular function so this could be the issue), either this: any or something more specific to tell typescript you did not mistakenly access this

UserSchema.virtual("username").get(function(this: { firstName: string, lastName: string}) {
  return this.firstName + " " + this.lastName ;
}) ;
like image 157
Titian Cernicova-Dragomir Avatar answered Oct 17 '22 19:10

Titian Cernicova-Dragomir


we can also create a user interface and make it like that :

IUser extends mongoose.Document{
firstname:string,
lastname:string
}

UserSchema.virtual("username").get(function(this:IUser) {
  return this.firstName + " " + this.lastName ;
}) ;
like image 36
kadiro Avatar answered Oct 17 '22 19:10

kadiro