【问题标题】:TypeScript Type Assertion Error: 'This expression is not callable Type '...' has no call signatures' is caused by a missing semicolonTypeScript 类型断言错误:'此表达式不可调用类型'...'没有调用签名'是由缺少分号引起的
【发布时间】:2021-04-11 19:24:33
【问题描述】:

这是我们原始代码的一个非常精简的版本:

  const start: number = 10
  const end: number = 20
  (someElement as HTMLInputElement).setSelectionRange(start, end)

然后在 20 下方有一条漂亮的红色小波浪线。指示此错误:此表达式不可调用类型“数字”没有调用签名。我们想出解决方案是添加一个分号:

  const start: number = 10
  const end: number = 20;
  (someElement as HTMLInputElement).setSelectionRange(start, end)

有谁知道它为什么会这样编译?我假设正在编译成 javascript 的打字稿正在解释该代码,并尝试将 end 变量作为函数调用。

  const start: number = 10
  const end: number = 20(someElement as HTMLInputElement).setSelectionRange(start, end)

【问题讨论】:

    标签: typescript type-assertion


    【解决方案1】:

    此行为并非特定于 TypeScript;您遇到的问题与使用纯 JavaScript 遇到的问题相同。 TypeScript 编译器没有选择将正确的 TypeScript 编译成不正确的 JavaScript;相反,它尽职尽责地将怪异的 TypeScript 转换为等效的怪异 JavaScript。

    一般来说,automatic semicolon insertion 不适用于如果行终止符之后的下一个标记可能在语法上有效,唯一的例外是禁止行终止符的特定位置之一(请参阅上面的 MDN 链接以获取这些地方的列表)。 20 之后的左括号 ( 显然可以解释为函数调用的开始,这在语法上是有效的。而且因为20之后没有禁止行终止符,所以不会插入分号。

    在 TypeScript 中,您会收到一个编译器错误警告,提示您正在调用没有调用签名的 20。该错误是一件好事,因为它使您有机会在进入运行时之前通过插入自己的分号来修复代码。因为同样,如果你用纯 JavaScript 编写上述代码(例如,没有类型断言),JavaScript 运行时将以相同的方式解释代码,你会得到运行时错误而不是编译器警告:

    // This is plain JS, not TS 
    try {
      const someElement = document.getElementsByTagName("input").item(0);
      const start = 10
      const end = 20
      (someElement).setSelectionRange(start, end)
    } catch (e) {
      console.log("OOPS I CAUGHT AN ERROR");
      console.log(e.message); // 20 is not a function
    }

    如果您运行该代码 sn-p(看不到 TypeScript 编译器),您将看到您的浏览器的 JavaScript 运行时发出 TypeError ,表明 20 不是一个有效的函数。

    【讨论】:

    • 说得好!谢谢你jcalz。出于好奇,您是否推荐其他编写类型断言的方法?
    • 有尖括号语法,但这会导致类似的问题,无论如何as 语法更好(尤其是对于 JSX/TSX 代码)。我真正的建议是在语句末尾使用分号。自动分号插入是奇怪,使人类更难推理语言。我认为它在某些时候会咬住每个人。
    猜你喜欢
    • 2019-09-10
    • 2018-12-25
    • 2017-09-01
    • 2021-02-06
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    相关资源
    最近更新 更多