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

当标记模板字面量的标签表达式为可选链或标签和模板之间存在可选链时,会发生 JavaScript 异常“标记模板不能与可选链一起使用”。

消息

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)

错误类型

哪里出错了?

有两种方法会导致此错误。第一种是如果标签表达式为可选链表达式,例如

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

第二种是如果 ?. 出现在标签和模板之间,例如

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

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

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

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

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

但是,无论如何这有点没有意义,因为可选链可以防止属性访问链中的错误,但在调用模板标签时却保证会生成错误。您可能仍然希望使用条件检查。

请注意,可选链仅作为标签表达式被禁止。您可以在嵌入式表达式中使用可选链,或将可选链用作标记模板表达式的整体。

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

另请参阅