如何为Nuxt自定义useFetch组合式函数定义TypeScript返回类型?
如何为Nuxt的useAPI组合式函数正确指定TypeScript返回类型?
我在Nuxt中创建了API插件和useAPI组合式函数,想要为其设置TypeScript返回类型,但始终无法让data获得正确的类型(一直是any)。
原始代码
API插件(plugins/01.api.ts)
export default defineNuxtPlugin((nuxtApp) => { const api = $fetch.create({ baseURL: useRuntimeConfig().public.baseUrl, }); return { provide: { api } } })
useAPI组合式函数(composables/useAPI.ts)
import type { UseFetchOptions } from 'nuxt/app'; export function useAPI<TResponse, T>( url: string | (() => string), options?: UseFetchOptions<T>, ): Promise<TResponse> { return useFetch(url, { ...options, $fetch: useNuxtApp().$api }); }
使用示例
interface fooBar { foo: string; bar: string; } async function initFooBar() { const { data } = await useAPI<fooBar>('/example-call'); console.log(data.value.data); }
问题在于,这里的data类型始终是const data: any,无法正确关联到fooBar接口。
我的尝试(不够简洁)
我通过手动定义返回类型让它可用,但写法过于繁琐:
export function useAPI<TResponse, T>( url: string | (() => string), options?: UseFetchOptions<T>, ): Promise<{ data: { value: TResponse | null } } & FetchResult<TResponse>> { return useFetch<TResponse>(url, { ...options, $fetch: useNuxtApp().$api }) as Promise<{ data: { value: TResponse | null } } & FetchResult<TResponse>>; }
简洁的正确解决方案
其实不需要手动拼接返回类型,直接复用Nuxt提供的UseFetchReturn类型即可,同时简化泛型参数:
import type { UseFetchOptions, UseFetchReturn } from 'nuxt/app'; export function useAPI<TResponse>( url: string | (() => string), options?: UseFetchOptions<TResponse> ): Promise<UseFetchReturn<TResponse>> { return useFetch<TResponse>(url, { ...options, $fetch: useNuxtApp().$api }); }
使用方式不变,但类型自动推断正确
interface fooBar { foo: string; bar: string; } async function initFooBar() { const { data } = await useAPI<fooBar>('/example-call'); // 此时data的类型是Ref<fooBar | null>,data.value会自动推断为fooBar | null console.log(data.value?.foo); }
关键说明
- 复用内置类型:Nuxt已经为
useFetch定义了完整的返回类型UseFetchReturn,直接导入使用即可,无需自己拼接复杂的类型结构。 - 简化泛型:只保留
TResponse作为响应数据的类型,传递给useFetch<TResponse>,这样UseFetchReturn<TResponse>会自动关联所有相关属性的正确类型。 - 无需类型断言:
useFetch的返回值本身就符合Promise<UseFetchReturn<TResponse>>,不需要额外的as断言。
内容的提问来源于stack exchange,提问作者Jakub Simek
相关产品推荐
相关产品推荐

