diff --git a/packages/nuxt3/src/app/composables/fetch.ts b/packages/nuxt3/src/app/composables/fetch.ts index c74e7c0c22..586616ba1e 100644 --- a/packages/nuxt3/src/app/composables/fetch.ts +++ b/packages/nuxt3/src/app/composables/fetch.ts @@ -13,13 +13,14 @@ export type UseFetchOptions< > = AsyncDataOptions & FetchOptions & { key?: string } export function useFetch< + ResT = void, ReqT extends string = string, - ResT = FetchResult, - Transform extends (res: ResT) => any = (res: ResT) => ResT, + _ResT = ResT extends void ? FetchResult : ResT, + Transform extends (res: _ResT) => any = (res: _ResT) => _ResT, PickKeys extends KeyOfRes = KeyOfRes > ( url: ReqT, - opts: UseFetchOptions = {} + opts: UseFetchOptions<_ResT, Transform, PickKeys> = {} ) { if (!opts.key) { const keys: any = { u: url } @@ -35,17 +36,18 @@ export function useFetch< opts.key = generateKey(keys) } - return useAsyncData(opts.key, () => $fetch(url, opts) as Promise, opts) + return useAsyncData(opts.key, () => $fetch(url, opts) as Promise<_ResT>, opts) } export function useLazyFetch< + ResT = void, ReqT extends string = string, - ResT = FetchResult, - Transform extends (res: ResT) => any = (res: ResT) => ResT, + _ResT = ResT extends void ? FetchResult : ResT, + Transform extends (res: _ResT) => any = (res: _ResT) => _ResT, PickKeys extends KeyOfRes = KeyOfRes > ( url: ReqT, - opts: Omit, 'lazy'> = {} + opts: Omit, 'lazy'> = {} ) { return useFetch(url, { ...opts, lazy: true }) } diff --git a/test/fixtures/basic/tests/types.ts b/test/fixtures/basic/tests/types.ts index c94132427e..8ac288a673 100644 --- a/test/fixtures/basic/tests/types.ts +++ b/test/fixtures/basic/tests/types.ts @@ -7,11 +7,14 @@ import { defineNuxtConfig } from '~~/../../../packages/nuxt3/src' import { useRouter } from '#imports' import { isVue3 } from '#app' +interface TestResponse { message: string } + describe('API routes', () => { it('generates types for routes', () => { expectTypeOf($fetch('/api/hello')).toMatchTypeOf>() expectTypeOf($fetch('/api/hey')).toMatchTypeOf>() expectTypeOf($fetch('/api/other')).toMatchTypeOf>() + expectTypeOf($fetch('/test')).toMatchTypeOf>() }) it('works with useFetch', () => { @@ -19,10 +22,13 @@ describe('API routes', () => { expectTypeOf(useFetch('/api/hey').data).toMatchTypeOf>() expectTypeOf(useFetch('/api/hey', { pick: ['baz'] }).data).toMatchTypeOf>() expectTypeOf(useFetch('/api/other').data).toMatchTypeOf>() + expectTypeOf(useFetch('/test').data).toMatchTypeOf>() expectTypeOf(useLazyFetch('/api/hello').data).toMatchTypeOf>() expectTypeOf(useLazyFetch('/api/hey').data).toMatchTypeOf>() expectTypeOf(useLazyFetch('/api/hey', { pick: ['baz'] }).data).toMatchTypeOf>() expectTypeOf(useLazyFetch('/api/other').data).toMatchTypeOf>() + expectTypeOf(useLazyFetch('/api/other').data).toMatchTypeOf>() + expectTypeOf(useLazyFetch('/test').data).toMatchTypeOf>() }) })