title: How to apply a decorator to all class methods using class decorator
body: <p>I'm using experimental typescript decorators to manage access control in express.</p>
  <pre class="lang-js prettyprint-override"><code>class AccountController extends Controller {
    
    login(req: Request, res: Response) {
      const { email, password } = req.body;
      const token = await this.model.login(email, password);
      return res.json({
        token
      });
    }
  
    @hasRole('ADMIN')
    list(req: Request, res: Response) {
      res.json({
        data: await this.model.findAll()
      });
    }
  }
  
  </code></pre>
  <p><code>hasRole</code> method decorator is working fine and I'm happy with it.</p>
  <p>The <code>Controller</code> implements REST methods:</p>
  <pre class="lang-js prettyprint-override"><code>class Controller {
    list(req: Request, res: Response) { // impl }
    get(req: Request, res: Response) { // impl } 
    create(req: Request, res: Response) { // impl }
    update(req: Request, res: Response) { // impl }
    delete(req: Request, res: Response) { // impl }
  }
  </code></pre>
  <p>The problem is, I have to apply the same decorators to most of other controllers and I find it very repetitive. For example, <code>StockController</code> should allow access to only <code>MERCHANT</code> role, and I have to do something like the following:</p>
  <pre class="lang-js prettyprint-override"><code>class StockController extends Controller {
    @hasRole('MERCHANT')
    list(req: Request, res: Response) { 
      return super.list(req, res);
    }
    @hasRole('MERCHANT')
    get(req: Request, res: Response) { 
      return super.get(req, res);
    } 
    @hasRole('MERCHANT')
    create(req: Request, res: Response) { 
      return super.create(req, res);
    }
    @hasRole('MERCHANT')
    update(req: Request, res: Response) { 
      return super.update(req, res);
    }
    @hasRole('MERCHANT')
    delete(req: Request, res: Response) { 
      return super.delete(req, res);
    }
  }
  </code></pre>
  <p>This approach is not only dull and repetitive but also unsafe, because if I add a method to <code>Controller</code> and accidentally forget to add the method to child controllers, they will allow unwanted access.</p>
  <p>I'd like to deal this problem with class decorator and use something like the following:</p>
  <pre class="lang-js prettyprint-override"><code>@requireRole('MERCHANT')
  class StockController extends Controller {}
  </code></pre>
  <p>However, from what I see in the <a href="https://www.typescriptlang.org/docs/handbook/decorators.html" rel="nofollow noreferrer">doc</a>:</p>
  <blockquote>
  <p>The class decorator is applied to the constructor of the class and can be used to observe, modify, or replace a class definition.</p>
  </blockquote>
  <p>As far as I understand it, I cannot implement &quot;method hook&quot; in class decorators. Any suggestions?</p>
  <p>For your information, <code>hasRole</code> decorator looks like the following:</p>
  <p><div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false">
  <div class="snippet-code snippet-currently-hidden">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>export function hasRole(role: string) {
    return function(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {
      const originalMethod = descriptor.value;
      descriptor.value = function(req: Request, res: Response) {
        const user = res.locals.user;
        if (user &amp;&amp; user.hasRole(role)) {
          originalMethod.apply(this, [req, res]);
        } else {
          res.status(403).json({});
        }
      }
    }
  }</code></pre>
  </div>
  </div>
  </p>