Decorators

Здесь собрана инфа по декораторм

Что это такое?

Декораторы это своего рода функции, которые предоставляют какие-либо метаданные для классов, методов, полей и тд. Так же декораторы являются экспериментальным инструментом, так что их поведение может меняться в зависимости от спецификаций языка.

По дефолту декоратор объявленный перед классом принимает в качестве аргумента конструктор этого класса, проверим :

function log(functionConstructor: Function) {
  console.log(functionConstructor);
}

@log
class User {
  constructor(
    public name: string,
    public age: number
  ) {
    console.log('I am user');
  }
}

// User(name, age) {
//   this.name = name;
//   this.age = age;
//   console.log('I am user');
// }

Какие бывают?

Как я понял различают следующие виды декораторов в TypeScript :

  • Декораторы класса

  • Декоратор методов

  • Декораторы Акцессора (get, set)

  • Декораторы свойства

  • Декораторы параметров

Как передать параметры?

Как передать параметры в декоратор класса я пока что-то не разобрался, видимо это не предусмотрено, однако есть способ сделать это используя функцию которая будет отдавать декоратор в место её вызова, например :

const classDecorator = (functionConstructor: Function): void => {
  functionConstructor.prototype.sayHi = function() {
    console.log(`Hi, my name is ${this.name}`)
  };
}

const functionThatReturnDecorator = (argument: any) => {
  // here you can do something with artuments
  console.log(argument);
  return classDecorator;
}

@functionThatReturnDecorator('argument') // argument
class User {
  constructor(
    private name: string
  ) {}
}

const test = new User('Greg');
(<any>test).sayHi(); // Hy, my name is Greg

Видимо параметры в принципе не передаются в декораторы, за исключением тех что попадают туда автоматически. Значит нужно постоянно юзать функции обёртки которые будут возвращать декораторы, как я реализовал это в примере :

const classDecorator = (argument: any) => {
  // here you can do something with arguments
  console.log(argument); // argument
  return (functionConstructor: Function): void => {
    functionConstructor.prototype.sayHi = function() {
      console.log(`Hi, my name is ${this.name}`) // Hi, my name is Greg
    };
  }
}

const methodDecorator = (firstArgument: string, secondArgument: string) => {
  //here you can do somehting with arguments
  console.log(firstArgument, secondArgument); // first argument second argument
  return (...args) => {
    console.log(args);
    // (3) [{…}, "login", {…}]
  }
}

@classDecorator('argument')
class User {
  constructor(
    private name: string
  ) {}

  @methodDecorator('first argument', 'second argument')
  login() {
    
  }
}

const test = new User('Greg');
(<any>test).sayHi();

Как видим в консоль попали 3 аргумента :

  1. Указатель на класс, в этом объекте перечислены все методы, свойства и тд

  2. Строковое представление метода к которому применяется декоратор

  3. Дескриптор метода(содержит параметры метода : configurable, enumerable, value, writable)

Для всех остальных декораторов принцип такой же, просто во все попадают разные аргументы, я думаю стоит перечислить их и подытожить :

Декоратор класса

  • Конструктор данного класса

Декоратор метода

  • Указатель на класс, в этом объекте перечислены все методы, свойства и тд

  • Строковое представление метода к которому применяется декоратор

  • Дескриптор метода(содержит параметры метода : configurable, enumerable, value, writable)

Декоратор акцессора

Аналогично декоратору метода

Декоратор свойства

  • Указатель на класс, в этом объекте перечислены все методы, свойства и тд

  • Строковое представление свойства к которому применяется декоратор

Декоратор параметра

Имеется ввиду параметр, как аргумент некой функции

  • Указатель на класс, в этом объекте перечислены все методы, свойства и тд

  • Строковое представление параметра к которому применяется декоратор

  • Порядковый индекс параметра в списке параметра функции

Last updated

Was this helpful?