Looks like it is not really feasible or very tricky still I’ll take a try.
Say we have a config data of a fluent structure for user to provide.
E.g.
configRoot:
fluentSubSection:
someProp: 12
valueOf: John Doe
toString: whatever
toJSON:
implementation: 'some-npm-one'
indentation: 2
How to make
- The user possible to provide really any data without any restrictions on property names
- Same time to be able to customize the functionality of ConfigNode representation class with some standard handlers such as
toString
,valueOf
,toJSON
Whether it possible it achieve the same functionality on some Symbol
/Proxy
/Other-Hucky
way. So that To split the functional and data level representation. Still to leave the natural data access through the pure properties way (without any accessors e.g. node.readProperty(‘propertyName’)
E.g.
const config = loadConfig('...')
console.log(config.configRoot.fluentSubSection.valueOf)
// John Doe
// plain content data access outputs the value provided by user
console.log(config.configRoot.fluentSubSection.toString)
// whatever
// plain content data access outputs the value provided by user
Still the ConfigNode instance it self should have some custom functionality under the hood (without harm for plain acccess to a user provided data properties) as
// Customize in some hucky way the functionality
ConfigNode[#toString_Symbol] = () => `[Custom ConfigNode - ${
Object.entries(this)
.map(
[key, value] => `${key}: ${value}`
).join(';')
}]`
ConfigNode[#toJSON_Symbol] = () => JSON.stringify(
{...this},
null,
this.toJSON?.indentation // the value from a data access level
)
console.log(String(config.configRoot.fluentSubSection))
// Should switch to some functional level access for toString implementation
// E.g. [Custom ConfigNode - someProp: 12; valueOf: John Doe; toString: whatever]
JSON.parse(config.configRoot.fluentSubSection)
// Should switch to custom JSON marshaling implementation
So how to customize toJSON
, toString
, valueOf
, etc.
related functionality of ConfigNode class and still to be able to provide same data properties as a plain regular values.
P.S. maybe someone grasp the idea and can see how to express the issue in more clear way please help as well 🙂
Anyway please any ideas are appreciated.
Thx
2
Answers
Actually for now I've found a partial solution with
Symbol.toPrimitive
which solves the issue fortoString
andvalueOf
.Actually it allows achieve the same just on step earlier and without populating the data properties scope with method functions.
The cons is that primitive would be the. same both for String and value representation. Still it works for my case.
Still for
toJSON
this doesn't seem to work. So I keep on researching.Basically you want to overload properties to return different type values based on the getter’s call context.
A short answer: SORRY that’s not C++ with type cast operator overloading.
This pattern is basically absent in JS and I strongly don’t recommend it.
You could try to overload though some way like this: