Dynamically initialize class properties using TypeScript decorators

InstructorRares Matei

Share this video with your friends

Send Tweet

Decorators are a powerful feature of TypeScript that allow for efficient and readable abstractions when used correctly. In this lesson we will look at how we can use decorators to initialize properties of a class to promises that will make GET requests to certain URLs. We will also look at chaining multiple decorators to create powerful and versatile abstractions.

Anup
~ 5 years ago

Inside @First decorator, prevInit() should be prevInit.call(target). Otherwise, value of "this" inside getter of @Get decorator will be undefined.

Tinkoff Dan
~ 5 years ago

Yes. There is truble with context into @First decorator. Could you please make changes to your lesson?

Rares Mateiinstructor
~ 5 years ago

That's a very good point, Anup! Thank you for pointing that out!!

I updated the lesson code on GitHub to correct for this. It's also slightly different than your suggestion:

function First() {
  return function(target: any, name: string) {
    const hiddenInstanceKey = "_$$" + name + "$$_";
    const prevInit = Object.getOwnPropertyDescriptor(target, name).get;
    const init = (prevInit: () => any) => {
      return prevInit()
        .then(response => response[0]);
    };
    Object.defineProperty(target, name, {
      get: function() {
        return this[hiddenInstanceKey] || (this[hiddenInstanceKey] = init(prevInit.bind(this)));
      },
      configurable: true
    });
  }
}

Reason for this is that in your example, target will actually refer to the constructor of our service, and not the actual instance. And we need them to reffer to the same instance always inside our gets, so we can store our promise, and re-use it correctly.