TypeScript用node-fetch时Omit RequestInit报TS2345编译错误
错误原因
这个TS2345错误本质是两套不兼容的Fetch API类型被混用导致的:
- TypeScript默认加载内置
lib.dom.d.ts中定义的全局RequestInit/HeadersInit类型,这是为浏览器环境原生Fetch API设计的类型 - 项目中使用的
node-fetch是Node.js端的独立Fetch实现,包内自带一套独立的RequestInit/HeadersInit类型,和DOM全局类型不兼容。错误提示中提到的raw方法就是node-fetch的Headers实例独有的方法,全局DOM的Headers类型不存在这个方法,因此TS判定两个类型无法互相赋值。
第一版代码能正常编译,是因为otherParams的类型通过Omit排除了headers属性,展开配置时不会引入全局类型中冲突的headers字段,手动传入的headers: Record<string, string>本身是node-fetch兼容的类型,因此不会触发冲突。
调整代码后,headers被从Omit排除列表中移除,otherParams继承了全局RequestInit里不兼容的headers类型,展开传入fetch的配置对象后就触发了类型不匹配错误。
解决方法
优先使用无副作用的方案:直接从node-fetch包导入它自身定义的RequestInit类型做类型约束,替换全局同名类型,修改后的可正常编译的代码如下:
import fetch, { type RequestInit } from 'node-fetch'; async function post( address: string, url: string, body: any, otherParams?: Omit<RequestInit, 'body' | 'method'> ) { const response = await fetch( `${address}${url}`, { method: 'POST', body: JSON.stringify(body), ...otherParams } ); return await response.json() }
这种方式下Omit产出的类型完全匹配node-fetch的参数要求,不会破坏其他场景的类型检查。
其余可选方案存在适用限制或风险,不做优先推荐:
- 纯Node.js后端项目如果完全不需要浏览器DOM类型,可以在
tsconfig.json的lib配置中移除"DOM"项,TS就不会加载全局Fetch类型,自动使用node-fetch的类型。但同构项目、混写前端代码的项目使用这个方案会导致其他依赖DOM类型的代码报错。 - 给传入fetch的配置对象添加
as RequestInit类型断言绕开校验:这种方式本质是强制让TS跳过类型检查,无法保证传入参数真的符合node-fetch的要求,容易隐藏参数错误导致的运行时问题。
内容的提问来源于stack exchange,提问作者Mateusz Kraiński
相关产品推荐
相关产品推荐

