typescript - TypeScript 类型断言错误:'此表达式不可调用类型'...'没有调用签名'是由缺少分号引起的
问题描述
这是我们原始代码的一个非常精简的版本:
const start: number = 10
const end: number = 20
(someElement as HTMLInputElement).setSelectionRange(start, end)
然后在20下方有一条漂亮的红色小波浪线。指示此错误:此表达式不可调用 Type 'Number' has no call signatures。我们想出解决方案是添加一个分号:
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;您遇到的问题与使用纯 JavaScript 遇到的问题相同。TypeScript 编译器没有选择将正确的 TypeScript 编译成不正确的 JavaScript;相反,它尽职尽责地将怪异的 TypeScript 转换为等效的怪异 JavaScript。
通常,如果行终止符之后的下一个标记可能在语法上有效,则自动分号插入不适用,唯一的例外是禁止行终止符的特定位置之一(有关这些位置的列表,请参见上面的 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
}
如果您运行该代码片段(看不到 TypeScript 编译器),您将看到浏览器的 JavaScript 运行时发出TypeError
一个20
无效函数。
推荐阅读
- python - 登录后(在我的 Django 应用程序中)我收到 403 错误
- unit-testing - 将 SWI-Prolog 代码结构化为多个算法和数据集的单元测试模块
- vue.js - 如何在点击时更新多个仪表板组件 - Vue.js
- android - 如何连接 dialogflow 和 actions.xml?
- c# - 如何访问新资源(图像)以设置为背景
- sql - 存储过程/字符串拆分功能在子查询中无法正常工作
- sql - 现在必须将表单中的必填字段设为可选,新字段变为必填,同时与原始字段具有可选关系
- javascript - 如何遍历继承的类属性?
- node.js - 如何从 node.js 后端获取客户端的错误对象?
- math - 在飞机上滑行