首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Typescript错误“此表达式不可调用...没有调用签名。(2349)”

问题分析

“此表达式不可调用...没有调用签名。(2349)” 是 TypeScript 中常见的错误之一。这个错误通常发生在尝试将一个不是函数的值当作函数来调用时。

基础概念

在 TypeScript 中,类型系统会严格检查变量和表达式的类型。当你尝试调用一个非函数类型的值时,TypeScript 编译器会抛出这个错误。

原因

这个错误的原因通常有以下几种:

  1. 变量类型错误:变量被错误地声明为函数类型,但实际上它不是。
  2. 类型推断错误:TypeScript 编译器在某些情况下可能会错误地推断变量的类型。
  3. 第三方库问题:使用的第三方库中可能存在类型定义错误。

解决方法

1. 检查变量类型声明

确保变量的类型声明正确。例如:

代码语言:txt
复制
let myFunction: () => void;
myFunction = 123; // 错误,123 不是函数

正确的做法是:

代码语言:txt
复制
let myFunction: () => void;
myFunction = () => {
  console.log('Hello, world!');
};

2. 使用类型断言

如果你确定某个值是函数类型,但 TypeScript 编译器无法正确推断,可以使用类型断言:

代码语言:txt
复制
let myValue: any = () => {
  console.log('Hello, world!');
};

(myValue as () => void)(); // 正确

3. 检查第三方库

如果你在使用第三方库时遇到这个错误,可能是库的类型定义文件有问题。可以尝试更新库到最新版本,或者查看库的文档和 issue 跟踪器,看看是否有其他人遇到类似问题。

4. 使用 TypeScript 的 noImplicitAny 选项

确保在 tsconfig.json 中启用了 noImplicitAny 选项,这可以帮助你捕获更多的类型错误:

代码语言:txt
复制
{
  "compilerOptions": {
    "noImplicitAny": true
  }
}

示例代码

假设有一个函数 processData,它接受一个函数作为参数:

代码语言:txt
复制
function processData(callback: (data: string) => void) {
  callback('Hello, world!');
}

let myCallback = 'not a function'; // 错误
processData(myCallback);

正确的做法是:

代码语言:txt
复制
let myCallback = (data: string) => {
  console.log(data);
};

processData(myCallback); // 正确

参考链接

通过以上方法,你应该能够解决“此表达式不可调用...没有调用签名。(2349)”这个 TypeScript 错误。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

TypeScript 演化史 — 第二章】基于控制流的类型分析 和 只读属性

使用 TypeScript 2.0,类型检查器会分析语句和表达式所有可能的控制流,在任何指定的位置对声明为联合类型的局部变量或参数产生最可能的具体类型(缩小范围的类型)。...因此,TypeScript 将 command 作为 string 类型的变量,并允许调用toLowerCase() 方法。...因此,对 join 方法的调用将正确地检查类型。 在 TypeScript 2.0 之前,编译器无法推断出上面的语义。...因此,没有从 command 变量的联合类型中删除字符串类型,并产生以下编译时错误: Property 'join' does not exist on type 'string | string[]...其思想是确保每个不可空的局部变量在使用之前都已正确初始化。 只读属性 在 TypeScript 2.0 中,readonly 修饰符被添加到语言中。

2K10

TypeScript 官方手册翻译计划【四】:函数

它们同样也是值,就和其它值一样,TypeScript 有很多种描述函数如何被调用的方式。接下来,让我们了解如何编写类型去描述函数吧。 函数类型表达式 最简单的描述函数的方式就是使用函数类型表达式。...但是,TypeScript 的函数类型表达式语法不允许声明属性。...会使用这个内部实现,并抛出一个实际上不可能出现的错误: myForEach([1, 2, 3], (a, i) => { console.log(i.toFixed());...在 TypeScript 中,我们可以编写重载签名来指定一个函数可以通过不同方式调用。...举个例子,下面的写法都是错误的,因为实现签名没有正确地匹配重载签名: function fn(x: boolean): void; // 参数类型不对 function fn(x: string): void

2.6K20
  • TypeScript 之 More on Functions

    然而上一节讲到的函数类型表达式并不能支持声明属性,如果我们想描述一个带有属性的函数,我们可以在一个对象类型中写一个调用签名(call signature)。...构造签名 (Construct Signatures) JavaScript 函数也可以使用 new 操作符调用,当被调用的时候,TypeScript 会认为这是一个构造函数(constructors)...第一个函数可以推断出返回的类型是 number,但第二个函数推断的返回类型却是 any,因为 TypeScript 不得不用约束的类型来推断 arr[0] 表达式,而不是等到函数调用的时候再去推断这个元素...在 TypeScript 中,我们可以通过写重载签名 (overlaod signatures) 说明一个函数的不同调用方法。...再次强调一下,写进函数体的签名是对外部来说是“不可见”的,这也就意味着外界“看不到”它的签名,自然不能按照实现签名的方式来调用。 实现签名对外界来说是不可见的。

    2.1K20

    typescript4.2新特性

    TypeScript 4.2中,内部结构就变得更加智能了,你可以在 TS Playground 中切换编译版本为4.2,你会发现类型推断很完美,如下图所示: 不可跟踪的rest元素 TS中我们可以用元组类型去标识一个数组的类型...中 # 提前到txt npx tsc --explainFiles > expanation.txt # 提前到vscode npx tsc --explainFiles | code - 改进逻辑表达式中的未调用函数检查...TypeScript的未调用函数检查现在适用于&&和||表达式。...lib.d.ts 的更新 noImplicitAny错误适用于宽松的yeild表达式: # 首先设置noImplicitAny为true "noImplicitAny": true 然后在4.2中运行以下代码...在4.2版本后,TypeScript设置了限制器以避免执行所有工作。 .d.ts扩展 不能在导入路径中使用 在TypeScript 4.2中,导入路径中包含.d.ts现在是错误的。

    89010

    TypeScript 官方手册翻译计划【十二】:类

    因为我也是 TypeScript 的初学者,所以无法保证翻译百分之百准确,若有错误,欢迎评论区指出; 翻译内容:暂定翻译内容为 TypeScript Handbook,后续有空会补充翻译文档的其它部分;...super(); } } 在 JavaScript 中,忘记调用 super 是一个常见的错误,但 TypeScript 会在必要时给你提醒。...TypeScript 提供了一些方法让我们可以减少或者防止这种错误的发生。...这种方法的利弊权衡和上面使用箭头函数的方法相反: JavaScript 的调用方可能仍然会在没有意识的情况下错误调用类方法 只会给每个类定义分配一个函数,而不是给每个类实例分配一个函数 仍然可以通过...类表达式 背景导读:类表达式(MDN) 类表达式和类声明非常相似。

    2.6K10

    TypeScript 演化史 — 第八章】字面量类型扩展 和 无类型导入

    以前,编译器过于严格,当导入一个没有附带类型定义的模块时,会出现一个错误: image.png 从 TypeScript 2.1 开始,如果模块没有类型声明,编译器将不再报错。...使用TypeScript 2.1,TypeScript 不是仅仅选择any类型,而是基于你后面的赋值来推断类型。 仅当设置了--noImplicitAny编译参数时,才会启用选项。...隐式any错误只会在编译器无法知道一个没有类型注解的变量的类型时才会报告。...} } 更好地检查表达式的操作数中的 null/undefined 在TypeScript 2.2中,空检查得到了进一步的改进。TypeScript 现在将带有可空操作数的表达式标记为编译时错误。...注意,从mixin函数返回的类表达式是一个未命名的类表达式,因为class关键字后面没有名称。与类声明不同,类表达式不必命名。

    4.6K10

    TypeScript 5.4:带来新的类型和一些 Break Change

    这是因为我们没有办法确保是否会在以后调用该函数。...这可能会导致 TypeScript 错误地拒绝有效的调用,还会接受有问题的调用,或者在捕获到错误时报告不正确的异常信息。...这个方法虽然行得通,但是有点别扭,因为 D 在 createStreetLight 的签名中可能不会再被用到。虽然在本例中还算可接受,但在签名中只使用一次类型参数通常是不太好的代码。...在 TypeScript 的早期版本中,当我们使用条件类型(就是那种基于条件分支决定类型的表达式)时,默认的行为有时会显得有些草率。...中,它会比较两个类型,如果看起来没有什么共同点或者交集没有什么用,它会直接告诉你交集是 never,这比以前简单判断要精准多了。

    30510

    TypeScript 演化史 — 第十章】更好的空值检查 和 混合类

    更好地检查表达式的操作数中的 null/undefined 在TypeScript 2.2中,空检查得到了进一步的改进。TypeScript 现在将带有可空操作数的表达式标记为编译时错误。...具体来说,下面这些会被标记为错误: 如果+运算符的任何一个操作数是可空的,并且两个操作数都不是any或string类型。...在 TypeScript 2.2 中,表达式password.length <= max是不正确的类型,如果你的应用程序正在严格的null检查模式下运行: function isValidPasswordLength...注意,从mixin函数返回的类表达式是一个未命名的类表达式,因为class关键字后面没有名称。与类声明不同,类表达式不必命名。...混合构造函数类型指仅有单个构造函数签名,且该签名仅有一个类型为 any[] 的变长参数,返回值为对象类型.

    2.6K10

    TypeScript 4.4 RC版来了,正式版将于月底发布

    ; // 错误,这里需要一个「string」值 arr[1] = 123; 索引签名特别适用于在外部表达大量代码的情况;但到目前为止,索引签名仅适用于 string 及 number 键(而且...TypeScript 也无法对某些 string 键子集的索引签名进行建模——例如用于描述一切以文本 data- 作为名称开头的属性的索引签名。...所以如果您使用 --strict 检查代码,选项将自动开启。但您也可能在 TypeScript 4.4 上遇到如下错误: 类型'unknown'上不存在属性'message'。...间接调用导入函数以提升合规性 在其他早期版本中,从 CommonJS、AMD 以及其他非 ES 模块系统处执行的导入调用操作会设置所调用函数的 this 值。...Promise { return false; } async function bar(): Promise { if (foo()) { // <- 没有错误提示

    2.6K20

    TypeScript 4.3 beta 版本正式发布:新增import语句补全,对模板字符串类型进行改进

    这里的问题有一部分是用户没有明确他们是要添加一个新方法还是要覆盖一个现有方法,这就是 TypeScript 4.3 添加 override 关键字的原因所在。...启用选项时,除非你显式使用一个 override 关键字,否则重写一个超类中的任何方法将生成错误。...),它将尝试为该表达式指定一个模板类型。...https://github.com/microsoft/TypeScript/pull/39175 static 索引签名 索引签名使我们可以在一个值上设置比一个类型显式声明更多的属性。...在 TypeScript 4.3 中,如果将具有一个联合 enum 类型的值与一个不可能相等的数字字面量进行比较,则类型检查器将发出错误

    1.1K40

    Node.js项目TypeScript改造指南

    本文讲的是如何将一个旧的 Node.js 项目使用 TypeScript 进行改造,包括目录结构调整、TypeScript-ESLint 配置、tsconfig 配置、调试、常见错误处理等。...报错 先不要着急去解决错误,因为还需要对 TypeScript 添加 ESLint 配置,避免改多遍,先把 ESLint 配置好,当然,你如果喜欢 Pretitter,可以把它加上,本文就不介绍如何集成...注意,下述解决报错有些地方用了“any大法”(不推荐),这是为了能让项目尽快 run 起来,毕竟是旧项目改造,不可能一步到位。...path 处的错误: 找不到模块“path”。...path_1 = require("path"); console.log(path_1.resolve); 可以看出导出单个属性时,并不会添加工具类,但会将单个属性导出修改为整个模块导出,并将原来的函数调用表达式修改为成员函数调用表达式

    4.4K20

    Node.js 项目 TypeScript 改造指南

    本文讲的是如何将一个旧的 Node.js 项目使用 TypeScript 进行改造,包括目录结构调整、TypeScript-ESLint 配置、tsconfig 配置、调试、常见错误处理等。...报错 先不要着急去解决错误,因为还需要对 TypeScript 添加 ESLint 配置,避免改多遍,先把 ESLint 配置好,当然,你如果喜欢 Pretitter,可以把它加上,本文就不介绍如何集成...注意,下述解决报错有些地方用了“any大法”(不推荐),这是为了能让项目尽快 run 起来,毕竟是旧项目改造,不可能一步到位。...path 处的错误: 找不到模块“path”。...path_1 = require("path"); console.log(path_1.resolve); 可以看出导出单个属性时,并不会添加工具类,但会将单个属性导出修改为整个模块导出,并将原来的函数调用表达式修改为成员函数调用表达式

    8.3K32

    TypeScript 演化史 -- 10】更好的空值检查 和 混合类

    更好地检查表达式的操作数中的 null/undefined 在TypeScript 2.2中,空检查得到了进一步的改进。TypeScript 现在将带有可空操作数的表达式标记为编译时错误。...具体来说,下面这些会被标记为错误: 如果+运算符的任何一个操作数是可空的,并且两个操作数都不是any或string类型。...在 TypeScript 2.2 中,表达式password.length <= max是不正确的类型,如果你的应用程序正在严格的null检查模式下运行: function isValidPasswordLength...注意,从mixin函数返回的类表达式是一个未命名的类表达式,因为class关键字后面没有名称。与类声明不同,类表达式不必命名。...混合构造函数类型指仅有单个构造函数签名,且该签名仅有一个类型为 any[] 的变长参数,返回值为对象类型.

    2.8K20

    Node.js项目TypeScript改造指南

    本文讲的是如何将一个旧的 Node.js 项目使用 TypeScript 进行改造,包括目录结构调整、TypeScript-ESLint 配置、tsconfig 配置、调试、常见错误处理等。...报错 先不要着急去解决错误,因为还需要对 TypeScript 添加 ESLint 配置,避免改多遍,先把 ESLint 配置好,当然,你如果喜欢 Pretitter,可以把它加上,本文就不介绍如何集成...注意,下述解决报错有些地方用了“any大法”(不推荐),这是为了能让项目尽快 run 起来,毕竟是旧项目改造,不可能一步到位。...path 处的错误: 找不到模块“path”。...path_1 = require("path"); console.log(path_1.resolve); 可以看出导出单个属性时,并不会添加工具类,但会将单个属性导出修改为整个模块导出,并将原来的函数调用表达式修改为成员函数调用表达式

    4.6K10

    TypeScript 4.2 Beta版本发布:带来诸多更新,营造更好的开发体验

    现在系统能够根据你在代码中的使用方式来打印出这些类型,这意味着作为 TypeScript 用户,你可以避免显示一些烦人的巨大类型,而这往往会转化为更好的.d.ts 文件输出、错误消息和快速信息及签名帮助中的编辑器内类型显示...在 TypeScript 4.2 中,模板字符串表达式现在总是以模板字面量类型开始。...TypeScript 4.2 包含一些重大更改,但我们认为它们应该不会太影响升级过程。 模板字面量表达式具有模板字面量类型 如前所述,模板字符串表达式现在以模板字面量类型开始。...更多信息参见相应的拉取请求: https://github.com/microsoft/TypeScript/pull/41891 noImplicitAny 错误,用于宽松的 yield 表达式 当捕获了一个...yield 表达式没有在上下文中类型化它(也就是说 TypeScript 不知道类型是什么)时,TypeScript 现在将发出一个隐式的 any 错误

    1.6K10

    TypeScript 真的值得吗?

    例如,如果表达式中的静态类型为 string,则在运行时,要保证在评估它时仅获得 string。 在健全的类型系统中,绝对不会在编译时或运行时产生表达式与预期类型不匹配的情况。...当然 TypeScript 有一定程度的健全性,并捕获以下类型错误: // 'string' 类型不可分配给 'number' 类型 const increment = (i: number): number...不健全以及 TypeScript 暴露在严格类型之外的各种转义符使它的有效性大大降低,不过这总比没有强一些。...例如在处理从 API 调用返回的 JSON 时,运行时类型检查将是有好处的。如果可以在类型级别上进行控制,则不需要那么多的错误种类和单元测试。...vscode中的TypeScript错误 通过 TypeScript 还可以增强重构的功能,并且在对修改后的代码进行编译时,可以立即识别出代码的改变(例如方法签名的更改)。

    1.4K20
    领券