如何为Nuxt3的customUseFetch添加泛型类型支持
解决Nuxt3自定义useFetch的泛型类型问题
问题背景
我知道在Nuxt3中可以通过泛型指定useFetch的返回类型:
const { data: res } = useFetch<ExType>("api_url here")
为了实现请求拦截逻辑,我封装了customUseFetch方法,但目前无法像原生useFetch那样指定泛型类型。当前封装代码如下:
export const customUseFetch = (url: string, options?: FetchOptions<unknown>) => { return useFetch(url, { ...options, async onResponse({ request, response, options }) { console.log('[fetch response]') }, async onResponseError({ request, response, options }) { console.log('[fetch response error]') }, async onRequest({ request, options }) { console.log('[fetch request]') }, async onRequestError({ request, options, error }) { console.log('[fetch request error]') } }) }
我希望能像原生方法一样使用自定义方法:
const { data: res } = customUseFetch<ExType>("api_url here")
尝试添加泛型后,useFetch的第二个参数出现类型错误:
const customUseFetch = <T>(url: string, options?: FetchOptions<T>) => { return useFetch<T>(url, { ・・・ }
解决方案
问题出在FetchOptions的泛型参数和useFetch接收的参数类型不匹配,useFetch实际需要的是UseFetchOptions类型(它扩展了FetchOptions并包含Nuxt特有的配置项)。以下是修正后的完整代码:
import type { UseFetchOptions } from 'nuxt/app' export const customUseFetch = <T>( url: string, options?: UseFetchOptions<T> ) => { return useFetch<T>(url, { ...options, async onResponse({ request, response, options }) { console.log('[fetch response]') // 可在此添加统一响应处理逻辑 }, async onResponseError({ request, response, options }) { console.log('[fetch response error]') // 可在此添加统一错误处理逻辑 }, async onRequest({ request, options }) { console.log('[fetch request]') // 可在此添加请求拦截逻辑,比如添加请求头token options.headers = { ...options.headers, Authorization: `Bearer ${localStorage.getItem('token')}` } }, async onRequestError({ request, options, error }) { console.log('[fetch request error]') } }) }
关键说明
- 类型匹配:使用
UseFetchOptions<T>替代FetchOptions<T>作为参数类型,确保和useFetch的参数类型完全兼容。 - 泛型传递:显式给
useFetch指定泛型<T>,保证返回的data类型为Ref<T | null>,和原生useFetch行为一致。 - 拦截器优先级:自定义的拦截器会覆盖传入
options中同名的拦截器,如果需要保留传入的拦截器逻辑,可以在自定义方法中调用原逻辑,示例如下:
async onResponse(context) { console.log('[fetch response]') // 调用传入的onResponse(如果存在) await options?.onResponse?.(context) }
使用示例
interface UserInfo { id: number name: string email: string } const { data: userInfo } = customUseFetch<UserInfo>('/api/user/info') // userInfo的类型为Ref<UserInfo | null>
内容的提问来源于stack exchange,提问作者harunaga
相关产品推荐
相关产品推荐

