# Why are template strings not allowed in optional chaining?

**URL:** <https://es.discourse.group/t/why-are-template-strings-not-allowed-in-optional-chaining/970>\
**Category:** I have questions\
**Created:** [September 5, 2021, 8:13pm UTC](https://es.discourse.group/t/why-are-template-strings-not-allowed-in-optional-chaining/970 "2021-09-05T20:13:52Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [September 5, 2021, 8:13pm UTC](https://es.discourse.group/t/why-are-template-strings-not-allowed-in-optional-chaining/970/1 "2021-09-05T20:13:52Z")

</div>

[Optional chaining grammar](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#prod-OptionalChain) contains these productions:

```javascript
OptionalChain :
  ?. TemplateLiteral
  OptionalChain TeplateLiteral

```

But then instead of defining runtime semantics, it makes these [early errors](https://tc39.es/ecma262/multipage/ecmascript-language-expressions.html#sec-left-hand-side-expressions-static-semantics-early-errors). There's a note explaining the purpose is to maintain consistency with code without optional chaining.

```javascript
String.raw`\t`; // works
String?.raw`\t` // syntax error

foo`x`; // works
foo?.`x`; // syntax error

```

Wouldn't it be more consistent if it simply worked (after null check) like a tagged template without optional chaining?

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [September 5, 2021, 9:09pm UTC](https://es.discourse.group/t/why-are-template-strings-not-allowed-in-optional-chaining/970/2 "2021-09-05T21:09:20Z")

</div>

Possibly because

```javascript
obj.prop`\t`

```

is

```javascript
(obj.prop)`\t`

```

so

```javascript
obj?.prop`\t`

```

would be

```javascript
(obj?.prop)`\t` // possibly resulting in (undefined)`\t`

```

and calling `undefined` as a tagged template literal throws a `TypeError`.

So while

```javascript
foo?.`x`

```

on its own may make sense, it may be confusing that a longer optional chain wouldn't compose with other features commonly paired with optional chaining like `??`.

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [September 5, 2021, 9:41pm UTC](https://es.discourse.group/t/why-are-template-strings-not-allowed-in-optional-chaining/970/3 "2021-09-05T21:41:20Z")

</div>

> [@aclaymore](#):
>
> so
> 
> ```javascript
> obj?.prop`\t`
> 
> ```
> 
> would be
> 
> ```javascript
> (obj?.prop)`\t` // possibly resulting in (undefined)`\t`
> 
> ```

I don't think those would be equivalent. For plain function calls, we have:

```javascript
obj?.prop('x') // undefined if obj is nullish, throws if obj.prop is nullish
obj?.prop?.('x') // undefined if obj?.prop is nullish
(obj?.prop)('x') // throws if obj?.prop is nullish

```

Tagged template is basically syntax sugar for function call, so I would expect:

```javascript
obj?.prop`x` // undefined if obj is nullish, throws if obj.prop is nullish
obj?.prop?.`x` // undefined if obj?.prop is nullish
(obj?.prop)`x` // throws if obj?.prop is nullish

```

---

<div class="post-metadata">

**Author:** ![aclaymore](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/aclaymore/32/501_2.png) [@aclaymore](https://es.discourse.group/u/aclaymore)\
**Post date:** [September 5, 2021, 11:13pm UTC](https://es.discourse.group/t/why-are-template-strings-not-allowed-in-optional-chaining/970/4 "2021-09-05T23:13:08Z")

</div>

There seems to be a dedicated issue where this was discussed as part of optional chaining design here:

> <https://github.com/tc39/proposal-optional-chaining/issues/54>
>
> From the \[current README\](https://github.com/tc39/proposal-optional-chaining/blo…b/f506e3f1138fd1f5d30676e74fc3c52d69601bdd/README.md#not-supported):
> \> The following are not supported due to a lack of real-world use cases:
> \> 
> \> optional construction: \`new a?.()\`
> \> optional template literal: \`\`a?.\`{b}\` \`\`
> \> constructor or template literals in/after an Optional Chain: \`\`new a?.b(), a?.b\`{c}\` \`\`
> 
> For this issue I'd like to understand:
> 
> 1) What are the reasons to NOT support tagged template literals?
> 2) If there's no great technical issues with allowing them, WHY NOT support tagged template literals?
> 
> For discussion purposes, I'll provide a somewhat silly & simple toy problem-esque example:
> 
> \`\`\`javascript
> /\*
> Prompt - In as few characters as you can, write a function 'splitOrJoin' that satisfies
> two requirements:
> 
> 1) If a string is passed in, split it and return an array of individual words, for example:
> splitOrJoin('split this into an array'); // \['split', 'this', 'into', 'an', 'array'\]
> 
> 2) If an array is passed in, join each element with spaces and return the resulting string:
> splitOrJoin(\['join', 'this', 'into', 'a', 'string'\]); // 'join this into a string'
> \*/
> 
> // Now your first instinct might be to write something with a ternary
> const splitOrJoin = input =\> input.split ? input.split\` \` : input.join\` \`; // this works
> 
> // Or, you could write it slightly differently
> const splitOrJoin = input =\> input\[input.split ? 'split' : 'join'\]\` \`; // also works
> 
> // But then you realize they're actually the same length when removing unnecessary characters
> splitOrJoin=i=\>i.split?i.split\` \`:i.join\` \` // 43 chars
> splitOrJoin=i=\>i\[i.split?'split':'join'\]\` \` // 43 chars
> 
> // Hmm, how else could we shorten it? Oh yeah! There's this new thing called optional chaining
> const splitOrJoin = input =\> input.split?.\` \` ?? input.join\` \`; // also would work
> 
> // or the shortened version
> splitOrJoin=i=\>i.split?.\` \`??i.join\` \` // 38 chars
> 
> // There! That's about as short as I can think to make it right now.
> \`\`\`
> 
> Now, you might think that code-golf is stupid (and I'd of course avoid using this pattern in production code--or anywhere you'd like your code to be readable and easily understood for that matter); but the fact is: \*\*tagged template literals are valid syntax in JavaScript\*\*.
> 
> Therefore, if you can write \`\`i.split\` \` \`\` I'd also expect you to be able to write \`\`i.split?.\` \` \`\` for the sake of completeness. Hopefully you can see past the ridiculousness of the example to see the reasoning for this.
> 
> So I'd like hear some logical argument around the two questions asked in the beginning. What are the reasons to arbitrarily (seemingly) disallow use of tagged template literals in conjunction with optional chaining? If there are, technically, no sound reasons for not supporting tagged template literals, why not allow them just like they're already allowed elsewhere?

---

<div class="post-metadata">

**Author:** ![lightmare](https://yyz2.discourse-cdn.com/free1/user_avatar/es.discourse.group/lightmare/32/843_2.png) [@lightmare](https://es.discourse.group/u/lightmare)\
**Post date:** [September 6, 2021, 7:55am UTC](https://es.discourse.group/t/why-are-template-strings-not-allowed-in-optional-chaining/970/5 "2021-09-06T07:55:36Z")

</div>

Thanks, that explains a lot.
