Декораторы свойств и методов доступа

Последнее обновление: 09.01.2023

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

Декоратор свойства представляет функцию, которая принимает два параметра:

function MyPropertyDecorator(target: Object, propertyKey: string){
	// код декоратора
}

Где первый параметр представляет конструктор класса, если свойство статическое, либо прототип класса, если свойство нестатическое. А второй параметр представляет имя свойства.

Определим простейший декоратор для свойства:

function format() {
  return function(target: Object, propertyKey: string) { 
    let value : string;
    const getter = function() {
      return "Mr./Ms." + value;     // изменяем возвращаемое значение
    };
    const setter = function(newVal: string) {
       if(newVal.length > 2) {   // добавляем проверку на длину строки
          value = newVal
      }     
    }; 
    // устанавливает геттер и сеттер для свойства
    Object.defineProperty(target, propertyKey, {    
      get: getter,
      set: setter
    });
  }
}

class User {
 
    @format()
    name: string;
    constructor(name: string){
        this.name = name;
    }
    print():void{
        console.log(this.name);
    }
}
let tom = new User("Tom");
tom.print();
tom.name = "Tommy";
tom.print();
tom.name = "To";
tom.print();

Декоратор format выполняет небольшое форматирование значение свойства. Для этого вначале мы получаем значение свойства. Создаем геттер, который возвращает отформатированное значение. Далее определяется сеттер, который устанавливает новое значение для свойства. В нем мы можем проинспектировать, как устанавливается свойство. Так, в данном случае не устанавливаем новое значение, если его длина меньше 2. И в конце удаляется старое свойство и создается новое с геттером и сеттером.

Вывод консоли браузера:

Mr./Ms.Tom
Mr./Ms.Tommy
Mr./Ms.Tommy

Декоратор метода доступа

Декоратор метода доступа принимает три параметра:

function decorator(target: Object, propertyName: string, descriptor: PropertyDescriptor){ 
	// код декоратора
}

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

Второй параметр представляет название метода.

Третий параметр представляет объект PropertyDescriptor.

Определим простейший декоратор метода доступа:

function validator(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
    const oldSet = descriptor.set;
 
    descriptor.set = function(value: string) {
        if (value === "admin") {
            throw new Error("Invalid value");
        }
		if(oldSet!==undefined) oldSet.call(this, value);
    }
}
class User {
 
    private _name: string;
    constructor(name: string){
        this.name = name;
    }
     
    public get name(): string {
        return this._name;
    }
    @validator
    public set name(n: string) {
        this._name = n;
    }
}
let tom = new User("Tom");
console.log(tom.name);
tom.name= "admin";
console.log(tom.name);

Декоратор validator переопределяет поведение сеттера с помощью свойства descriptor.set. Если передаваемое сеттеру значение представляет строку "admin", то генерируется ошибка.

Декоратор достаточно применить только к геттеру или к сеттеру, в любом случае он будет сразу применяться к обоим аксессорам.

И, к примеру, при вызове инструкции tom.name= "admin"; мы столкнемся с ошибкой:

Accessor decorator in TypeScript
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850