Skip to content

Instantly share code, notes, and snippets.

@wentout
Last active July 23, 2022 06:02
Show Gist options
  • Save wentout/5fb2e37648552d93e8096809ff0e2aa9 to your computer and use it in GitHub Desktop.
Save wentout/5fb2e37648552d93e8096809ff0e2aa9 to your computer and use it in GitHub Desktop.
monotonic types on field definitions and objects
let value = 123;
const MyGetSetTestClass = class {
get get() {
console.log('g0')
return function () {
console.log('g1')
return ++value;
}
}
set get(value) {
throw new Error('setter for getter is out of control');
}
get set() {
console.log('s0')
return function (_value) {
console.log('s1', _value)
value = _value;
return value;
}
}
set set(value) {
throw new Error('setter for setter is out of understanding');
}
}
debugger;
const myGetSetField = new MyGetSetTestClass;
const myGetSetTestingObject = {};
const myGetSetTestingObjectSecond = {};
try {
Reflect.defineProperty(myGetSetTestingObject, 'testMonoField', myGetSetField);
Reflect.defineProperty(myGetSetTestingObjectSecond, 'testMonoFieldSecond', myGetSetField);
} catch (error) {
debugger;
console.error(error);
}
console.log(myGetSetTestingObject.testMonoField);
myGetSetTestingObject.testMonoField = 123;
try {
console.log('assign to getter');
myGetSetField.get = 1234;
} catch (error) {
debugger;
console.error(error);
}
try {
console.log('assign to setter');
myGetSetField.set = 1234;
} catch (error) {
debugger;
console.error(error);
}
console.log(myGetSetTestingObject.testMonoField);
myGetSetTestingObjectSecond.testMonoFieldSecond = 12345;
console.log('!!!', myGetSetTestingObject.testMonoField);
const ErrorsNames = {
ACCESS_DENIED: 'ACCESS DENIED'
};
const TEST = function (value) {
const receiver = Object.getPrototypeOf(this);
Object.assign(receiver, {
get() {
const invocationThis = Object.getPrototypeOf(this);
if (invocationThis !== receiver) {
throw new ReferenceError(ErrorsNames.ACCESS_DENIED);
}
return value;
},
set(replacementValue) {
const invocationThis = Object.getPrototypeOf(this);
if (invocationThis !== receiver) {
throw new TypeError(ErrorsNames.ACCESS_DENIED);
}
return value = replacementValue;
},
configurable: false,
enumerable: true,
// writable: false
});
return receiver;
};
const myObject = {};
Object.setPrototypeOf(myObject, TEST.prototype);
const myOtherObject = {};
Object.setPrototypeOf(myOtherObject, TEST.prototype);
// the start of the magic
const myField = new TEST('123');
Object.defineProperty(myObject, 'myField', myField);
Object.defineProperty(myOtherObject, 'myField', myField);
console.log('onInit: myObject.myField :', myObject.myField);
console.log('onInit: myOtherObject.myField :', myOtherObject.myField);
myObject.myField = 321;
console.log('onMade: myObject.myField :', myObject.myField);
console.log('onMade: myOtherObject.myField :', myOtherObject.myField);
myOtherObject.myField = 777;
console.log('onMade: myObject.myField :', myObject.myField);
console.log('onMade: myOtherObject.myField :', myOtherObject.myField);
const ErrorsNames = {
ACCESS_DENIED: 'ACCESS DENIED'
};
const TEST = function (value) {
const receiver = Object.getPrototypeOf(Object.getPrototypeOf(this));
Object.assign(receiver, {
get() {
const invocationThis = this;
if (invocationThis !== receiver) {
throw new ReferenceError(ErrorsNames.ACCESS_DENIED);
}
return value;
},
set(replacementValue) {
const invocationThis = this;
if (invocationThis !== receiver) {
throw new TypeError(ErrorsNames.ACCESS_DENIED);
}
return value = replacementValue;
},
configurable: false,
enumerable: true,
// writable: false
});
return receiver;
};
const myObject = {};
Object.setPrototypeOf(TEST.prototype, myObject);
const myField = new TEST('123');
// Reflect.defineProperty(myObject, 'myField', new TEST('123'));
Object.defineProperty(myObject, 'myField', myField);
console.log(myObject.myField)
myObject.myField = 321;
console.log(myObject.myField)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment