TS - decorator relies on another irrespective of their position within the class


Is it possible to consistently run function decorator @A before @B, regardless of their position within the class?


class Example {

@A()
public method1(): void { ... }

@B()
public method2(): void { ... }

@A()
public method3(): void { ... }

}

In the scenario above, I am seeking to ensure that the @A decorators for method1 and method3 are executed prior to @B() no matter where the methods are located in the class.

Answer №1

I discovered a clever technique using ReflectMetadata:

A special decorator


export const A =
  () =>
  (consumer: any, methodName: string, descriptor: PropertyDescriptor) => {
    const existingAMethods =
      Reflect.getOwnMetadata("A_METHODS", consumer.constructor) || []
    const options: {
      consumer,
      methodName,
      descriptor
    }
    existingAMethods.push(options)
    Reflect.defineMetadata(
      "A_METHODS",
      existingAMethods,
      consumer.constructor
    )
  }

Another unique decorator


export const B =
  () =>
  (consumer: any, methodName: string, descriptor: PropertyDescriptor) => {
    const existingBMethods =
      Reflect.getOwnMetadata("B_METHODS", consumer.constructor) || []
    const options: {
      consumer,
      methodName,
      descriptor
    }
    existingBMethods.push(options)
    Reflect.defineMetadata(
      "B_METHODS",
      existingBMethods,
      consumer.constructor
    )
  }

Introducing the final one called "C"

export const C = () =>
  (constructor: Function): void => {
    const options =
      Reflect.getOwnMetadata("A_METHODS", constructor) || []
    // Perform actions related to A
    const options =
      Reflect.getOwnMetadata("B_METHODS", constructor) || []
    // Perform actions related to B
  }

Application example

@C()
class Example {

  @A()
  public method1(): void { ... }

  @B()
  public method2(): void { ... }

  @A()
  public method3(): void { ... }

}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Invoking a nested class while declaring types in TypeScript

This is the specific format of data that I am in need of this.structure=[ { id: 1, name: 'root1', children: [ { id: 2, name: 'child1' }, { id: 3, name: 'child2' } ] }, { ...

Understanding Mongodb: the process of populating a schema that is referenced within another schema using an API

Looking to make adjustments to my Api in order to populate a referenced schema. Here's the schema I am working with: export const taskSchema = new Schema ({ user:{ type: String, required: true }, project: { type ...

Is there a way to set up custom rules in eslint and prettier to specifically exclude the usage of 'of =>' and 'returns =>' in the decorators of a resolver? Let's find out how to implement this

Overview I am currently working with NestJS and @nestjs/graphql, using default eslint and prettier settings. However, I encountered some issues when creating a graphql resolver. Challenge Prettier is showing the following error: Replace returns with (r ...

What is the best way to merge an array of objects into a single object?

Is there a way to dynamically convert object1 into object2, considering that the keys like 'apple' and 'water' inside the objects are not static? const object1 = { apple:[ {a:''}, {b:'&apos ...

Enhancing NG Style in Angular 6 using a custom function

Today, my curiosity lies in the NG Style with Angular 6. Specifically, I am seeking guidance on how to dynamically update [ngStyle] when utilizing a function to determine the value. To better illustrate my query, let me present a simplified scenario: I ha ...

Securing Angular 2 routes with Firebase authentication using AuthGuard

Attempting to create an AuthGuard for Angular 2 routes with Firebase Auth integration. This is the implementation of the AuthGuard Service: import { Injectable } from '@angular/core'; import { CanActivate, Router, Activated ...

Transforming Angular 4's folder structure for improved architecture simplicity

I am faced with the challenge of organizing files and folders within an Angular 4 project in a way that allows for easy reorganization. Currently, my approach looks like this: ├───core │ │ core.module.ts │ │ index.ts │ │ │ ...

Is there a way to define one type parameter directly and another type parameter implicitly?

I am currently utilizing a UI-library that offers an API for constructing tables with a structure similar to this: type Column<Record> = { keys: string | Array<string>; render: (prop: any, record: Record) => React.ReactNode; } The l ...

Tips for simulating difficult private attributes within a class during unit testing in TypeScript

Is there a way to mock the value of a hard private property in a unit test? For example, how can I expect something like expect(event.getEventHis()).toBeEqual(['a', 'b']) export class EventController { #event: []; constructor() { ...

What is the best way to click on a particular button without activating every button on the page?

Struggling to create buttons labeled Add and Remove, as all the other buttons get triggered when I click on one. Here's the code snippet in question: function MyFruits() { const fruitsArray = [ 'banana', 'banana', & ...

Tips for properly implementing an enum in TypeScript when using the React useState hook

What's the correct way to utilize my useState hook? I have this enum type: export enum Status { PENDING = 'pending', SUCCESS = 'success', ERROR = 'error', } And the useState hook: const [isValid, setIsValid] = use ...

Error encountered: YouCompleteMe is unable to locate the necessary executable 'npm' for the installation of TSServer

While attempting to install YouCompleteMe for vim and enable support for Java and Javascript, I followed the instructions provided here. My command was: sudo /usr/bin/python3.6 ./install.py --java-completer --ts-completer Unfortunately, I encountered an ...

Typescript custom sorting feature

Imagine I have an array products= [{ "Name":'xyz', 'ID': 1 }, { "Name":'abc', 'ID': 5 }, { "Name":'def', 'ID': 3 } ] sortOrder=[3,1,5] If I run the following code: sortOrder.forEach((item) =&g ...

Tips to avoid multiple HTTP requests being sent simultaneously

I have a collection of objects that requires triggering asynchronous requests for each object. However, I want to limit the number of simultaneous requests running at once. Additionally, it would be beneficial to have a single point of synchronization afte ...

The module 'csstype' is nowhere to be found, according to error code TS2307

I've encountered an issue with Visual Studio 2017 not compiling my code. Recently, I integrated Typescript, React, and Webpack into our solution, and everything seemed to be working fine. However, upon attempting to build our MVC application, it star ...

Upon the initial loading of GoJS and Angular Links, nodes are not bypassed

Hey there, I'm currently working on a workflow editor and renderer using Angular and GoJS. Everything seems to be in order, except for this one pesky bug that's bothering me. When the page first loads, the links don't avoid nodes properly. H ...

Typescript Declarations for OpenLayers version 6

The package @types/openlayers found at https://www.npmjs.com/package/@types/openlayers only provides type definitions for version 4.6 of OpenLayers. This is clearly stated in the top comment within the file index.d.ts. If types for OpenLayers 6 are not av ...

How do you implement a conditional radio button in Angular 2?

I am facing an issue with two radio buttons functionality. When the first radio button is selected and the user clicks a button, the display should be set to false. On the other hand, when the second radio button is chosen and the button is clicked, ' ...

The variable "theme" is referenced prior to being initialized

https://i.stack.imgur.com/QL0pa.png One of the variables in my code, theme, is set to be assigned a value from a for loop: let theme: Theme for (const themeObj of themeList) { const [muiThemeName, muiTheme] = Object.entries(themeObj)[0]!; if (muiThem ...

Accessing an Excel file in TypeScript using the .xlsx format

After extensive research, I managed to find a solution for reading the .xlsx file in a TypeScript environment. Once implemented, I documented the solution along with a question and answer. The file "demo.xlsx" contains UserIds and Code, displayed in the i ...