语法错误:标记模板不能与可选链一起使用

标记模板文字 的标记表达式是 可选链 时,或者标记和模板之间存在可选链时,会发生 JavaScript 异常 "标记模板不能与可选链一起使用"。

¥The JavaScript exception "tagged template cannot be used with optional chain" occurs when the tag expression of a tagged template literal is an optional chain, or if there's an optional chain between the tag and the template.

信息

¥Message

SyntaxError: Invalid tagged template on optional chain (V8-based)
SyntaxError: tagged template cannot be used with optional chain (Firefox)
SyntaxError: Cannot use tagged templates in an optional chain. (Safari)

错误类型

¥Error type

SyntaxError

什么地方出了错?

¥What went wrong?

有两种方法可以获取此错误。第一个是如果标签表达式是可选链表达式,如下所示:

¥There are two ways to get this error. The first one is if the tag expression is an optional chain expression, like this:

js
String?.raw`Hello, world!`;
console.log?.()`Hello, world!`;
Number?.[parseMethod]`Hello, world!`;

第二个是如果 ?. 出现在标签和模板之间,如下所示:

¥The second one is if ?. occurs between the tag and the template, like this:

js
String.raw?.`Hello, world!`;

标签中的可选链接是被明确禁止的,因为它没有很好的用例,并且预期结果是什么尚不清楚(应该是 undefined 还是模板的值,好像它没有被标记?)。你需要将可选链接转换为其底层条件(有关更多信息,请参阅 可选链接)。

¥Optional chaining in the tag is specifically forbidden because there's no great use case for it, and what the result is expected to be is unclear (should it be undefined or the template's value as if it's untagged?). You need to translate the optional chaining to its underlying condition (see optional chaining for more information).

js
const result =
  String.raw === null || String.raw === undefined
    ? undefined
    : String.raw`Hello, world!`;

请记住,可选链接仅在带括号的单元内短路。如果将标记表达式括起来,则可选链不会导致错误,因为现在标记不会短路,结果很清楚(标记将生成 undefined,然后导致标记模板抛出)。

¥Remember that optional chaining only short-circuits within a parenthesized unit. If you parenthesize your tag expression, the optional chaining will not cause an error, because now the tag does not short-circuit and the result is clear (the tag will produce undefined and then cause the tagged template to throw).

js
(console?.log)`Hello, world!`; // Throws if console?.log is undefined

然而,这无论如何都有点荒谬,因为可选链可以防止属性访问链中出现错误,但保证在调用模板标记时会产生错误。你可能仍想使用条件检查。

¥However this is a bit nonsensical anyway because optional chaining prevents errors inside the property access chain, but is then guaranteed to generate an error when calling the template tag. You would probably still want to use a conditional check.

请注意,可选链接仅作为标签表达式被禁止。你可以在嵌入表达式中使用可选链接,也可以在整个标记模板表达式上使用可选链接。

¥Note that optional chaining is only forbidden as the tag expression. You can use optional chaining inside the embedded expressions, or use optional chaining on the tagged template expression as a whole.

js
console.log`Hello, ${true.constructor?.name}!`; // ['Hello, ', '!', raw: Array(2)] 'Boolean'
console.log`Hello`?.toString(); // undefined

也可以看看