Optional chaining on the left side in Javascript

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:

  • https://www.typescriptlang.org/play
  • https://play.kotlinlang.org/

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!