Is it possible to use the optional chaining operator in the left side of an assignment =
in Javascript?
const building = {}
building?.floor?.apartment?.number = 3; // Is this possible?
You can use optional chaining when attempting to call a method which may not exist. This can be helpful, for example, when using an API in which a method might be unavailable, either due to the age of the implementation or because of a feature which isn't available on the user's device.
Optional chaining is a safe and concise way to perform access checks for nested object properties. The optional chaining operator ?. takes the reference to its left and checks if it is undefined or null. If the reference is either of these nullish values, the checks will stop and return undefined.
Conclusion # The error "The left-hand side of an assignment expression may not be an optional property access" occurs when we try to use optional chaining (?.) to assign a property to an object. To solve the error, use an if statement that serves as a type guard instead.
Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil . If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil , the property, method, or subscript call returns nil .
It's not possible, sorry.
In the interest of a canonical answer: The MDN documentation isn't explicit about this, but you can read the proposal's README in GitHub for more information. It says:
The following is not supported, although it has some use cases; see Issue #18 for discussion:
- optional property assignment:
a?.b = c
In the linked issue are the comments 1:
OK, seems like there's a rough agreement in this thread not to do the write case in the first iteration.
and 2:
We also discussed this question at TC39, and the committee did not seem so interested in adding this feature.
So I guess it's not likely to happen anytime soon.
Hope that helps; good luck!
I was looking myself into this and regretfully, as the other commenters already stated, an assignment via optional chaining appears to not be possible in typescript as of the time of writing and will indeed yield you the parser warning:
The left-hand side of an assignment expression may not be an optional property access.
When attempting something akin to:
class A{
b?: string;
}
var a = new A();
a?.b = "foo";
But since optional assignments are useful at times, there's still the old fashioned way of using single line if-queries like so:
class A{
b?: string;
}
try{a.b = "foo0"} // throws TypeError
catch(e){console.log(e.toString())} // a is undefined
if(a) a.b = "foo1"; // skips
console.log(a); // a is undefined
var a: any;
if(a) a.b = "foo2"; // skips
console.log(a); // a is undefined
a = null;
if(a) a.b = "foo3"; // skips
console.log(a); // a is null
a = undefined;
if(a) a.b = "foo4"; // skips
console.log(a); // a is undefined
a = new A();
if(a) a.b = "foo5"; // runs
console.log(a); // a is A: {"b": "foo5"}
if(null) console.log("bar0"); // skips
if(undefined) console.log("bar1"); // skips
if({}) console.log("bar2"); // runs
if({something: "there"}) console.log("bar3"); // runs
if([]) console.log("bar4"); // runs
if(["not empty"]) console.log("bar5"); // runs
To demonstrate an example where it is in fact possible, here's a kotlin snippet:
class A{
var b: B? = null;
var title: String? = null;
override fun toString():String = "Instance of class A with title: ${this.title} and b of value: ${this.b.toString()}";
}
class B{
var title: String? = null;
override fun toString():String = "Instance of class B with title: ${this.title}";
}
fun main() {
var a:A? = null;
println(a); // null
try{a!!.title = "foo0"} catch(e:Exception){println(e)} // NPE
a?.title = "foo1";
println(a); // null
a = A();
println(a); // Instance of class A with title: null and b of value: null
a?.title = "foo2";
println(a); // Instance of class A with title: foo2 and b of value: null
try{a!!.b!!.title = "bar0"} catch(e:Exception){println(e)} // NPE
a?.b?.title = "bar1";
println(a); // Instance of class A with title: foo2 and b of value: null
a?.b = B();
println(a); // Instance of class A with title: foo2 and b of value: Instance of class B with title: null
a?.b?.title = "bar2";
println(a); // Instance of class A with title: foo2 and b of value: Instance of class B with title: bar2
a?.b?.let{it.title = "bar3"}
println(a); // Instance of class A with title: foo2 and b of value: Instance of class B with title: bar3
}
Now I'm not arguing that one language is better than the other but rather that purpose and philosophy require different design choices and decide the resulting shape of the tool which ultimately any programming or script language is. While also being slightly annoyed that I can not assign values to an optional chaining in typescript.
Edit: I used these Playground sites which are useful to test such things:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With