Я пытаюсь понять, как написать декоратор, который использует уже существующее свойство класса и создает сопоставленную или преобразованную версию этого свойства, которая также обновляется каждый раз, когда обновляется значение исходного свойства.
Например, @upperCase
создаст новое свойство (с ключом `${DECORATED_PROPERTY}_UPPERCASE`
), которое преобразует строку в верхний регистр, а @double
создаст новое свойство (с ключом `${DECORATED_PROPERTY}_DOUBLE`
), которое удваивает значение каждого числа в массиве.
class MyClass {
@upperCase word = 'hamburger';
@double numbers = [1, 2, 3, 4];
}
const foo = new MyClass();
console.log(foo.word_UPPERCASE); // 'HAMBURGER'
console.log(foo.numbers_DOUBLE); // [2, 4, 6, 8]
foo.word = 'new word';
// See the derived property update in accordance with the original when the original changes value
foo.word_UPPERCASE = 'NEW WORD';
Я поиграл с Object.defineProperty
и его свойствами get
и set
, но, похоже, ничего не работает. Например, когда я пробую эту реализацию для @upperCase
:
export function upperCase(target:any, propertyKey:string) {
let value:string = target[propertyKey];
const getter = function () {
return value.toUpperCase(); // Error below gets thrown at this line
}
const setter = function (newVal:string) {
value = newVal;
}
Object.defineProperty(target, `${propertyKey}_UPPERCASE`, {
get: getter,
set: setter,
})
}
и использовать его в классе как @upperCase word:string = 'foobar';
, если я затем console.log(this['word_UPPERCASE'])
, я получаю следующую ошибку:
TypeError: can't access property "toUpperCase", value is undefined
выбрано в строке, прокомментированной выше, где getter
пытается вернуть value.toUpperCase()
.
return this[propertyKey].toUpperCase();
. Не очевидно, что должен делать сеттер, поскольку вы не можете снять что-то с верхнего регистра. - person Aluan Haddad   schedule 22.07.2020defineProperty
, но все, что мне было нужно, это геттер. - person davidlav   schedule 23.07.2020get
очень полезно и позволяет создавать действительно неизменяемые объекты. Вероятно, вы захотите добавитьenumerable: true
в свой дескриптор. Дополнительные сведения см. в MDN. - person Aluan Haddad   schedule 24.07.2020