TypeScript Method Decorators
In this guide you'll learn how to work with method decorators in the TypeScript programming language, including how you can customize function behavior by adding new behavior.
Guide Tasks
  • Read Tutorial
  • Watch Guide Video
Video locked
This video is viewable to users with a Bottega Bootcamp license

In this guide, we're going to talk about method decorators. So we've talked about how we can implement class decorators and this time we're going to get into how we can work with the passing in layering decorators on top of functions. Now the proper term for it even though you're putting them on top of functions is method decorator. So just keep that in mind especially if you're researching it outside of this.

So right here we have our accounts payable class and we have a constructor that doesn't do anything. And then we have our detailed logging system that is being used as a class decorator.

@detailedLog('billing')
 class AccountsPayable {
  constructor() {}
}

function detailedLog(dashboard : string) {
  if(dashboard == 'billing') {
    console.log('Working with the billing department');
    return function (tatget : Object) {};
  } else {
    return function (target : Object) {};
  }
}

var post = new AccountsPayable;

Now let's say that we've built in the ability for deleting an account so we can say delete account and it's going to be a method and inside of it we're just going to console log out. Deleting Account. This is all well and good. However let's say that we want to build our permission structure by using the decorator pattern what we can do is actually create a function that will work as a permission structure for admins. We're not going to build in the actual permission structure because that would need a full blown application and you need to have. The ability to check if users authenticate all kinds of things so here we're just going to mimic it and say function admin and inside of this if you remember back to right here are arguments required for a for a basic class decorator are pretty tiny. You really just need the target and that's it with a method decorator. There are quite a bit more extensive. So I'm going to type this out.

So we're to have a target which is going to be. Of type Object and then we're going to have a property key which is going to be of type string. A descriptor. Which is going to be of type typed property descriptor. If you notice this is an interface so this is an interface provided to us from typescript and the data type for this is going to be any. And this is going to return any. Now inside of this. We're going to just have a basic console log statement and it's going to say doing admin check. So in a real life application you would check you'd query the user database check and see. OK is this user a admin user. If so let them through if not he can block them and redirect them and then the last thing is we're going to return the descriptor. So that you know you don't really have to worry about what is actually going return because in real life what that descriptor would essentially be doing is that that's what the permission structure to be connected to. But for right now I just want to show you how you can create these. Then most importantly how you can call them.

So in order to call a method decorator I'm going to come into the class itself and here we're going to start with an @ symbol and then say admin and that is all we have to do. So now if we come down. And we already instantiated our class. Now if I type in post delete account and run this we're going to see if it calls our admin decorator properly. So come to the terminal. And run node 032_method_decorator. And as you can see that worked.

@detailedLog('billing')
 class AccountsPayable {
  constructor() {}

  @admin
  deleteAccount() {
    console.log('Deleting account...');
  }
}

function detailedLog(dashboard : string) {
  if(dashboard == 'billing') {
    console.log('Working with the billing department');
    return function (tatget : Object) {};
  } else {
    return function (target : Object) {};
  }
}

function admin(trget : Object, propertyKey : string, descriptor : TypedPropertyDescriptor<any>) : any {
  console.log("Doing admin check");
  return descriptor;
}

var post = new AccountsPayable;
post.deleteAccount();

So we have three items. Let's see the order because the order is always a little bit interesting. So the first thing that got printed out is doing admin work. So notice how the very first thing that gets printed out is actually our method decorator. That even happens even before our decorator for the class so that's important. So our decorators are getting run First it says doing admin check inside of the admin decorator. The next thing is working in the billing department which is our class decorator here. And lastly, we have deleting account which is the code that was actually inside of here.

Now, this is important because imagine that this really was functional and I was talking to a database. What this means and it's a good thing is that this decorator code is going to get run before the code inside of here. And that's kind of the key to making this work as if the deleting account ran before doing the admin check. It would be pointless because the account would have been deleted and then. We would have gone and checked the permission structure. But here what it's doing is it's going to check in and we're saying OK is this an admin or not. If so then let them through. If not then we can you know perform redirection or you know doing anything like that.

So this is I think a great way of being able to implement a permission structure. And so that's that's really the key to it. Now going back to the function. It's just a basic function. It takes in these set of arguments and these are the basic ones that are going to be used when you're creating a method decorator. Like I said most of the time you're not going to be creating a lot of method decorators in angular 2 development. Instead, you're going to be implementing the ones that the angular 2 team created for you to use. So that's a very critical thing because when I have walked through this with students before this kind of code scared the heck out of him and for good reason. If you don't know what each one of these items are then that can be pretty confusing. But what the important thing to know is more of the behavior that this does. So if you bring in a library in for permission structure and the instructions say OK implement. This method decorator. On top of any process or on top of any page that you want to block users from then you now would know how to do that.

So that's my main goal in teaching you about decorator's isn't as much on how to create them from scratch. It's more on how to be able to implement them in the programs and now I think that you should have a pretty good understanding of how that side of it works. So now that you have all this knowledge on getting these implemented in the next guide I'm going to take a look at some real angular 2 code so you can see what this looks like in an actual program.

Resources