How to create method decorators in typescript and what are the use cases of decorators?



If you are a python developer, you are already aware of decorators, they are a special type of declarations which can be attached various members, In typescript there are a different kind of decorators such as class, method, accessor and property decorators.

How to enable decorators in Typescript?

In you tsconfig.json, enable the flag as true for experimentalDecorators and emitDecoratorMetadata

Use cases of decorators

Decorators can be used during analytical, logging, instrumentation, validation, and run-time checks scenarios, but there are many advanced scenarios where you can take advantage of decorators especially in Python. But in typescript, we will show you how to execute a backend function only when the user is authenticated.

export function VerifyAuthorization(
  _target: any,
  _propertyKey: string,
  descriptor: TypedPropertyDescriptor<(...args: any[]) => Promise<void>>
) {
  const fn = descriptor.value!;
  descriptor.value = async function DescriptorValue(...args: any[]) {
    try {
      if (!args[1][AppConstants.IS_USER_LOGGED]) {
        throw new GraphQLError(ErrorConstants.USER_NOT_AUTHORIZED);
      }
      return await fn.apply(this, args);
    } catch (error) {
      throw new GraphQLError(error);
    }
  };
  return descriptor;
}

As you have seen above, we have created the above decorator to perform whether the user is authenticated and if only we will make further database queries, you can check here in detail, how we are benefitted from this decorator https://github.com/allabouttech0803/graphql-mongodb-typescript-blog/blob/main/src/controllers/blogs.controller.ts

Otherwise, we should be writing lines in each function to check whether IS_USER_LOGGED is true, hence we preferred to create a decorator for this usage, and also in case we need to make any update in the logic for authorization, we just have to make it only once in the decorator.

Let's understand the above method decorator in-depth

Below are the three parameter passed to the method decorators

  • 1st argument: Prototype of the class
  • 2nd argument: Name of the member
  • 3rd argument: Property descriptor of the member

We have used the above method decorator in all the methods of class those are retrieving or updating the data in the database and before doing any transaction in the database, below is one such method in which, we can check whether is there any authorization context is passed before retrieving the information from the server

  @VerifyAuthorization
  getBlogs(args: any, ctx: any) {
    return Blogs.find()
      .populate({
        path: 'comments',
        model: 'Comment',
        populate: {
          path: 'user',
          model: 'User',
        },
      })
      .then((blogs: any) => {
        return blogs;
      });
  }

References

0
0