Express配置中无法调用函数,请求检查TypeScript类型定义问题
Express + TypeScript 报错 "This expression is not callable. Type 'Iexpress' has no call signatures." 及代码类型修正
核心错误原因
你自定义的Iexpress接口仅声明了static方法,但Express模块导出的是一个可调用的函数(调用它会生成Express应用实例),你的接口没有包含这个调用签名,因此TypeScript判定它无法被调用。
最优解决方案:使用官方类型包(避免手动写类型)
手动编写全量类型极易出错,Express生态的官方类型都维护在@types包中,先安装依赖:
npm install @types/express @types/body-parser @types/node --save-dev
修改后的完整代码(直接复用官方类型):
import express from 'express'; import bodyParser from 'body-parser'; import path from 'path'; // 直接用官方提供的Express应用实例类型 const app = express(); if (process.env.NODE_ENV === "development") { console.log("in development."); } else { console.log("in production."); } /* App Config */ app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(express.static(path.join(__dirname, "../dist"))); /* Server Initialization */ // req、res使用官方定义的Request/Response类型 app.get("/", (req: express.Request, res: express.Response) => res.sendFile("index.html", { root: path.join(__dirname, "../dist") }) ); const port: string | number = process.env.PORT || 3000; app.listen(port, () => console.log( `Server initialized on: http://localhost:${port} // ${new Date()}` ) );
若坚持手动修正原有类型(不推荐)
如果一定要用require并手动定义类型,至少要给Iexpress添加调用签名,同时修正其他错误类型:
// 先定义应用实例的类型 interface IApp { get(path: string, handler: (req: any, res: { sendFile: (path: string) => void }) => void): void; use(middleware: any): void; listen(port: string | number, callback: () => void): void; } // 给Iexpress添加调用签名,指定调用后返回IApp类型 interface Iexpress { (): IApp; static: (path: string) => any; } const expressQ: Iexpress = require("express"); // bodyParser的方法返回的是中间件函数,不是string const bodyParser: { urlencoded(options: { extended: boolean }): any; json(): any; } = require("body-parser"); // path.join接收任意数量的字符串参数,无需指定参数名 const path: { join(...paths: string[]): string; } = require("path"); const app: IApp = expressQ(); // 后续代码保持原有逻辑,但注意req不是string类型,此处用any临时替代,建议还是用官方类型
其他类型错误说明
- 你把
req定义为string完全错误:Express的请求对象是包含请求头、参数等信息的复杂对象,正确类型是express.Request。 bodyParser.urlencoded()/bodyParser.json()返回的是Express中间件函数,不是string,你的类型定义完全偏离实际。path.join的参数是任意数量的字符串,无需指定参数名为__dirname,官方类型已适配这种场景。app.listen的返回值是http.Server实例,不是string,原类型定义错误。
内容的提问来源于stack exchange,提问作者Виктория
相关产品推荐
相关产品推荐

