SyntaxError: tagged template cannot be used with optional chain

带标签的模板字面量的标签表达式是可选链,或者标签和模板之间存在可选链时,会发生 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)

错误类型

SyntaxError

哪里出错了?

有两种情况会引发此错误。第一种是标签表达式是一个可选链表达式,如下所示:

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

另见