Consider the following TypeScript code with a property decorator that logs when a property is accessed:
function logProperty(target: any, key: string) {
let value = target[key];
const getter = () => {
console.log(`Get: ${key} => ${value}`);
return value;
};
const setter = (newVal: any) => {
console.log(`Set: ${key} => ${newVal}`);
value = newVal;
};
Object.defineProperty(target, key, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
class Person {
@logProperty
name: string = "Alice";
}
const p = new Person();
p.name = "Bob";
console.log(p.name);What will be printed to the console?
function logProperty(target: any, key: string) { let value = target[key]; const getter = () => { console.log(`Get: ${key} => ${value}`); return value; }; const setter = (newVal: any) => { console.log(`Set: ${key} => ${newVal}`); value = newVal; }; Object.defineProperty(target, key, { get: getter, set: setter, enumerable: true, configurable: true }); } class Person { @logProperty name: string = "Alice"; } const p = new Person(); p.name = "Bob"; console.log(p.name);
Think about when the setter and getter functions are called during property access and assignment.
The property decorator replaces the property with a getter and setter that log access and assignment. When p.name = "Bob" runs, the setter logs the new value. When console.log(p.name) runs, the getter logs the current value and returns it. The initial assignment to "Alice" happens before the decorator is applied to the instance, so it is not logged.
In TypeScript, when you create a property decorator, what are the arguments passed to the decorator function?
Property decorators do not receive a property descriptor argument.
Property decorators receive two arguments: the target object (the prototype for instance properties or the constructor for static properties) and the property name as a string or symbol. They do not receive a property descriptor, unlike method decorators.
Look at this TypeScript code with a property decorator intended to log access to a property:
function logAccess(target: any, key: string) {
let value = target[key];
Object.defineProperty(target, key, {
get() {
console.log(`Getting ${key}`);
return value;
},
set(newVal) {
console.log(`Setting ${key} to ${newVal}`);
value = newVal;
},
enumerable: true,
configurable: true
});
}
class Example {
@logAccess
data = 123;
}
const e = new Example();
console.log(e.data);
e.data = 456;
console.log(e.data);However, when running this code, no logs appear when accessing or setting data. Why?
Think about how instance properties are initialized versus prototype properties.
The decorator modifies the property on the class prototype. But the instance property data is created on each instance during construction, shadowing the prototype property. So the getter and setter on the prototype are never called. To fix this, the decorator must define the property on the instance or use a different approach.
Which of the following TypeScript property decorators correctly sets a default value 42 for a property?
Remember that property decorators do not receive a descriptor and cannot return one. Use Object.defineProperty properly.
Option D correctly uses Object.defineProperty on the target to set the property with a default value 42, writable and configurable. Option D sets the value directly on the prototype, but this does not define the property descriptor. Option D tries to return a descriptor, but property decorators cannot return a descriptor. Option D defines a getter that always returns 42 but ignores the setter, which is not a default value but a constant.
Given this TypeScript code with a property decorator that replaces the property with a getter and setter storing the value in a private symbol:
const _value = Symbol('value');
function storeValue(target: any, key: string) {
Object.defineProperty(target, key, {
get() {
return this[_value];
},
set(val) {
this[_value] = val;
},
enumerable: true,
configurable: true
});
}
class Data {
@storeValue
prop = 10;
}
const d = new Data();
d.prop = 20;
After running this code, how many own properties does the object d have?
Consider where the symbol property is stored and whether it is enumerable.
The property decorator defines a getter and setter on the prototype, so prop is not an own property of the instance d. The symbol property _value is set on the instance when the setter runs, but symbols are not enumerable and do not count as own enumerable properties. The instance d has no own enumerable properties after this code runs.