Last active
July 23, 2022 06:02
-
-
Save wentout/5fb2e37648552d93e8096809ff0e2aa9 to your computer and use it in GitHub Desktop.
monotonic types on field definitions and objects
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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