deepak
deepak

Reputation: 45

Declaring type for this in function body

In the typescript documentation the following example is given on how to use type for this usage inside a callback function. Can someone please help me to understand how the callback will work here?

interface DB {
  filterUsers(filter: (this: User) => boolean): User[];
}
 
const db = getDB();
const admins = db.filterUsers(function (this: User) {
  return this.admin;
});

Upvotes: 1

Views: 53

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074355

For methods and traditional functions (not arrow functions), this is effectively a read-only parameter whose value is passed to the function by the code calling it. (More here.) When the function's code runs, this is whatever the caller set it to (explicitly or implicitly).

The this pseudo-parameter in TypeScript lets you tell TypeScript what type this will have when the function is called. So the DB interface's filterUsers method is defined saying that this will refer to a User object when the callback is called.

You don't have to repeat it when you write the callback (though you can), TypeScript will infer it from the DB interface's definition:

const db = getDB();
const admins = db.filterUsers(function() {
  return this.admin;
  //     ^? −−−−− here, `this` has the type `User`
});

In a comment you've asked:

How the function will bound to an User instance here ?

Code in filterUsers will ensure that when it calls the callback, it does so with this set to a user. It might do that with either Function.prototype.call or Function.prototype.apply:

// Notional (not literal!) code for a `filterUsers` method:
filterUsers(callback: (this: User) => boolean): User[] {
    const filtered = this.users.filter(user => callback.call(user));
    //                                                 ^^^^^   ^
    //                                                         |
    //                          the value to use as `this` −−−−+
    return filtered;
}

.call and .apply allow you to explicitly state what this should be when calling a function.


It's probably worth noting that this would be an unfortunate way for DB's filterUsers to be defined. It would be much more convenient for users of the interface if the user were passed as a simple parameter (as with Array.prototype.filter and such), not as this. But it's a synthetic example in the documentation for explaining this syntax.

Upvotes: 3

Related Questions