I am currently in the process of developing a customized version inspired by ts-optchain
. The main goal is to create a functionality that produces a duplicate of the original object with specific modifications incorporated without altering the original object. The untouched areas of the object are referenced and copied over into the shallow copy operation using Object.assign(...)
.
The test I am working on validating is outlined below:
const example = { a: { b: { c: { d: 5 } } } };
const out = osc(example).a.b.c.d(6);
expect(out).to.be.deep.eq({ a: { b: { c: { d: 6 } } } });
... where osc
(optional set chain) is the function designed to emulate the behavior of opt-chain
's oc
function.
I anticipate the outcome to be somewhat similar to
Object.assign({}, example, {a: Object.assign({}, example.a, {b: Object.assign({}, example.a.b, {c: Object.assign({}, example.a.b.c, {d: 6})})})});
The approach above can be cumbersome to write, read, and maintain. Hence the decision to develop this function.
The implementation
Here is my current attempt at creating this functionality:
// Code implementation goes here...
The issue at hand
However, I am encountering an error message stating:
osc(...).a.b.c.d is not a function
. This is where my confusion sets in. Upon returning from the functions osc
(and _osc
), the type is TSOSCType
, extending the interface TSOSCDataSetter
. The TSOSCDataSetter
interface specifies that the object inheriting the interface is callable:
interface TSOSCDataSetter<R, T> {
(value: Readonly<T>): Readonly<R>;
}
The returned value from both osc
and _osc
is a Proxy
representing the type TSOSCType
(similar to how ts-optchain
operates). This Proxy object aids in constructing the chain and completing the object chain's typing. But more importantly, for this question, it implements the apply
method:
apply: function (target, thisArg, args: [Readonly<V>]): Readonly<R> {
return set_chain(args[0]);
}
Given this setup, why is the type TSOSCType
not callable?