You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node 10中Express与TypeScript结合http2的类型兼容问题咨询

解决Express + TypeScript 2.8.x与Node.js http2模块的类型兼容问题

你遇到的问题其实很典型——Express的官方类型定义(@types/express)确实是基于Node.js的http模块设计的,而http2.createServer期望的处理函数参数类型是Http2ServerRequest/Http2ServerResponse,和Express的Request/Response类型天然不兼容,而且目前确实没有官方的@types/express-http2包,因为Express本身是通过兼容http接口的方式支持http2的,类型层面没做针对性适配。

下面给你几个可行的解决方案,按优先级排序:

1. 优化类型断言,避免频繁any转换

你可以自定义交叉类型,把Express的请求响应类型和http2的类型合并,同时给app做一次安全的类型转换,不用每次路由处理都重复写冗长的断言:

import * as express from 'express';
import * as http2 from 'http2';

// 定义合并后的类型,同时保留Express和http2的所有属性方法
type Http2ExpressRequest = express.Request & http2.Http2ServerRequest;
type Http2ExpressResponse = express.Response & http2.Http2ServerResponse;

// 一次性转换app的类型,替代多次`as any`的写法
const http2CompatibleApp = app as express.Express & 
  ((req: http2.Http2ServerRequest, res: http2.Http2ServerResponse) => void);

// 创建http2服务器
const server = http2.createServer({}, http2CompatibleApp).listen(8080);

// 路由中直接使用合并后的类型
app.get('/', (req: Http2ExpressRequest, res: Http2ExpressResponse) => {
  // 直接调用http2的push方法,无需额外转换
  res.push('/static/style.css', {
    status: 200,
    headers: { 'content-type': 'text/css' }
  }).end('body { margin: 0; padding: 1rem; }');
  
  res.send('Hello HTTP/2 with Express!');
});

这种方式比用any更安全,能保留完整的类型提示和编译检查,同时大幅减少重复代码。

2. 扩展Express的全局类型定义

你可以在项目中创建自定义的类型扩展文件,让Express的Request/Response自动包含http2的类型,彻底告别手动断言:

  1. 在项目根目录创建typings/express/index.d.ts文件,内容如下:
import * as http2 from 'http2';

declare module 'express' {
  // 让Express的Request继承Http2ServerRequest的所有属性
  interface Request extends http2.Http2ServerRequest {}
  // 让Express的Response继承Http2ServerResponse的所有属性
  interface Response extends http2.Http2ServerResponse {}
}
  1. 修改tsconfig.json,确保这个目录被包含在类型扫描范围内:
{
  "compilerOptions": {
    // 其他配置...
    "typeRoots": ["./node_modules/@types", "./typings"]
  },
  "include": ["./src/**/*", "./typings/**/*"]
}

之后你在代码中直接使用Express的请求响应对象,就能直接调用http2的方法(比如res.push()),不需要任何类型转换。

3. 更换为原生支持http2的Web框架

如果可以接受更换框架,推荐使用Fastify——它原生支持http2,且有完善的TypeScript类型定义,对http2的支持是一等公民,不需要处理类型兼容问题,同时性能比Express更出色。

示例代码:

import fastify from 'fastify';
import fs from 'fs';

// 初始化支持http2的Fastify实例(注意http2需要HTTPS环境)
const app = fastify({
  http2: true,
  https: {
    key: fs.readFileSync('./server.key'),
    cert: fs.readFileSync('./server.cert')
  }
});

// 路由中直接使用http2功能
app.get('/', async (request, reply) => {
  // 直接调用push方法
  reply.push('/static/style.css', {
    status: 200,
    headers: { 'content-type': 'text/css' }
  }).end('body { background: #f5f5f5; }');
  
  return { message: 'Hello HTTP/2 with Fastify!' };
});

app.listen({ port: 8080 }, (err) => {
  if (err) {
    console.error(err);
    process.exit(1);
  }
  console.log('HTTP/2 server running on https://localhost:8080');
});

另外,Koa也可以结合http2使用,且有官方TypeScript类型支持,但Koa的中间件风格和Express差异较大,需要一定的学习成本。

内容的提问来源于stack exchange,提问作者Michael Tiller

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:47:09