TypeScript中如何为自定义fetch方法引入并扩展RequestInit类型?
解决React中自定义fetch方法的RequestInit类型引入与扩展问题
1. 修复ESLint的"RequestInit is not defined"报错
你遇到的ESLint报错是因为它未识别到RequestInit属于浏览器DOM API的全局类型——VSCode能识别是因为读取了tsconfig的lib配置,但ESLint需要单独配置环境:
- 在你的ESLint配置文件(如
.eslintrc.js)中,确保env包含browser:
module.exports = { env: { browser: true, es2021: true, node: true, }, // 其他ESLint配置项 };
- 如果仍有问题,可在文件顶部添加三斜线指令,显式声明依赖DOM类型定义:
/// <reference lib="dom" />
2. 为options定义继承RequestInit并支持扩展的类型
你可以通过两种方式实现需求:自定义接口继承,或直接使用交叉类型。
方式一:自定义接口继承RequestInit
先定义一个继承RequestInit的接口,再添加你的自定义属性:
/// <reference lib="dom" /> // 定义带扩展属性的接口 interface FetchServerOptions extends RequestInit { // 这里添加你的自定义属性,比如: skipAuth?: boolean; customHeader?: string; } export const fetchServer = async <T>( url: string, options: FetchServerOptions = {}, ): Promise<T> => { // 处理URL、请求头等自定义逻辑 const alteredOptions = { ...options }; // 示例:统一添加请求头 alteredOptions.headers = { ...alteredOptions.headers, 'Content-Type': 'application/json', ...(options.customHeader && { 'X-Custom-Header': options.customHeader }), }; // 调用原生fetch const rawResponse = await fetch(url, alteredOptions); // 处理响应并转为泛型T类型 if (!rawResponse.ok) { throw new Error(`Request failed: ${rawResponse.status}`); } return rawResponse.json() as Promise<T>; };
方式二:使用交叉类型直接声明
如果不需要复用扩展类型,可直接在参数中用交叉类型组合RequestInit和自定义属性:
/// <reference lib="dom" /> export const fetchServer = async <T>( url: string, options: RequestInit & { skipAuth?: boolean; customHeader?: string } = {}, ): Promise<T> => { // 同上面的处理逻辑 const alteredOptions = { ...options }; const rawResponse = await fetch(url, alteredOptions); return rawResponse.json() as Promise<T>; };
3. 处理strict模式下的默认值问题
如果你的tsconfig开启了strict: true,直接给options设= {}可能会触发类型检查警告(空对象不完全符合RequestInit结构),可以改成可选参数并在函数内合并默认值:
export const fetchServer = async <T>( url: string, options?: FetchServerOptions, ): Promise<T> => { // 合并默认配置与传入参数 const finalOptions = { method: 'GET', headers: {}, ...options, } as FetchServerOptions; // 后续处理逻辑 const rawResponse = await fetch(url, finalOptions); return rawResponse.json() as Promise<T>; };
内容的提问来源于stack exchange,提问作者Unapedra
相关产品推荐
相关产品推荐

