No, this is not possible in the general case since the data dependencies in a system can be very tricky.
As a simple example, consider the following setting:
var person = {...};
var someOtherObject = {p: person};
We have two references to the shared object: person
and someOtherObject.p
. A modification person.age = 20
would be reflected through both references. A reassignment person = {...person, age: 20}
would leave stale data in someOtherObject
.
In this simple case, detecting the dependency might be feasible. But in the general case, the transpiler would have to solve the halting problem – impossible.
In languages other than JavaScript, this can become possible. E.g. Rust strictly limits what references can be active at the same time. There cannot be any other reference when there is a mutable reference active.
Within JavaScript, such transformations might be possible for those cases where the transpiler can prove that there won't be a conflict. However, such cases will be limited to very simple cases where the object being modified is created very closely, as JavaScript has reference semantics and no concept of exclusive ownership. This transformation is potentially more difficult than type inference, which is difficult enough (read: also impossible) for vanilla JavaScript.
person
is updated, and (2) how should it know to change constant 20 to 21?