I want to create dynamic non-configurable properties using Proxy. I tried this:
const proxy = new Proxy({}, {
getOwnPropertyDescriptor() {
return {
configurable: false,
enumerable: false,
};
},
});
console.log(Reflect.getOwnPropertyDescriptor(proxy, 'test'));
But I'm getting an error:
TypeError: 'getOwnPropertyDescriptor' on proxy: trap reported non-configurability for property 'test' which is either non-existant or configurable in the proxy target
MDN says that:
A property cannot be reported as non-configurable, if it does not exists as an own property of the target object or if it exists as a configurable own property of the target object.
But it doesn't explain what's the reasoning behind this.
Is there any workaround for this error?
Not really. This is due to the desirable invariant that, if you observe a non-configurable property in an object, it can't magically disappear. And if it's also non-writable, its value must not change.
If you couldn't rely on this, getOwnPropertyDescriptor
would be basically useless.
Enforcing you not to use non-configurable properties, or defining them in the target, implies that you won't violate this invariant, because the invariant holds on the target by construction. That is, ECMAScript doesn't allow you to use the Proxy customizations in a way that breaks these invariants.
Some of the internal method invariants defined in 6.1.7.3 are essential integrity invariants. These invariants are explicitly enforced by the proxy object internal methods specified in this section. An ECMAScript implementation must be robust in the presence of all possible invariant violations.
So either report the property as configurable, or define non-configurable properties in the target.
If you want dynamic properties I recommend to just lie say the property is configurable. And then add a defineProperty
trap which returns false
, effectively preventing redefinitions.