mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
refactor(nuxt): enhance useFetch
and useLazyFetch
request type (#4825)
Co-authored-by: Daniel Roe <daniel@roe.dev>
This commit is contained in:
parent
8298cf27e6
commit
3a822c7177
@ -10,7 +10,7 @@ Nuxt provides `useFetch`, `useLazyFetch`, `useAsyncData` and `useLazyAsyncData`
|
||||
|
||||
Within your pages, components and plugins you can use `useFetch` to universally fetch from any URL.
|
||||
|
||||
This composable provides a convenient wrapper around `useAsyncData` and `$fetch`. It automatically generates a key based on URL and fetch options, as well as infers API response type.
|
||||
This composable provides a convenient wrapper around `useAsyncData` and `$fetch`. It automatically generates a key based on URL and fetch options, provides type hints for request url based on server routes, and infers API response type.
|
||||
|
||||
::ReadMore{link="/api/composables/use-fetch"}
|
||||
::
|
||||
|
@ -1,6 +1,6 @@
|
||||
# `useFetch`
|
||||
|
||||
This composable provides a convenient wrapper around [`useAsyncData`](/api/composables/use-async-data) and [`$fetch`](/api/utils/$fetch). It automatically generates a key based on URL and fetch options, as well as infers API response type.
|
||||
This composable provides a convenient wrapper around [`useAsyncData`](/api/composables/use-async-data) and [`$fetch`](/api/utils/$fetch). It automatically generates a key based on URL and fetch options, provides type hints for request url based on server routes, and infers API response type.
|
||||
|
||||
## Type
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { FetchOptions, FetchRequest } from 'ohmyfetch'
|
||||
import type { FetchOptions } from 'ohmyfetch'
|
||||
import type { TypedInternalResponse, NitroFetchRequest } from 'nitropack'
|
||||
import { computed, isRef, Ref } from 'vue'
|
||||
import type { AsyncDataOptions, _Transform, KeyOfRes, AsyncData, PickFrom } from './asyncData'
|
||||
@ -48,11 +48,11 @@ export function useFetch<
|
||||
const key = '$f' + _key
|
||||
|
||||
const _request = computed(() => {
|
||||
let r = request as Ref<FetchRequest> | FetchRequest | (() => FetchRequest)
|
||||
let r = request
|
||||
if (typeof r === 'function') {
|
||||
r = r()
|
||||
}
|
||||
return (isRef(r) ? r.value : r) as NitroFetchRequest
|
||||
return (isRef(r) ? r.value : r)
|
||||
})
|
||||
|
||||
const {
|
||||
@ -85,7 +85,7 @@ export function useFetch<
|
||||
}
|
||||
|
||||
const asyncData = useAsyncData<_ResT, ErrorT, Transform, PickKeys>(key, () => {
|
||||
return $fetch(_request.value, _fetchOptions)
|
||||
return $fetch(_request.value, _fetchOptions) as Promise<_ResT>
|
||||
}, _asyncDataOptions)
|
||||
|
||||
return asyncData
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { withQuery } from 'ufo'
|
||||
import type { NitroErrorHandler, NitroFetchRequest } from 'nitropack'
|
||||
import type { NitroErrorHandler } from 'nitropack'
|
||||
// @ts-ignore TODO
|
||||
import { normalizeError, isJsonRequest } from '#internal/nitro/utils'
|
||||
|
||||
@ -36,7 +36,7 @@ export default <NitroErrorHandler> async function errorhandler (_error, event) {
|
||||
}
|
||||
|
||||
// HTML response
|
||||
const url = withQuery('/__nuxt_error', errorObject as any) as NitroFetchRequest
|
||||
const url = withQuery('/__nuxt_error', errorObject as any)
|
||||
const html = await $fetch(url).catch((error) => {
|
||||
console.error('[nitro] Error while generating error response', error)
|
||||
return errorObject.statusMessage
|
||||
|
14
test/fixtures/basic/types.ts
vendored
14
test/fixtures/basic/types.ts
vendored
@ -135,6 +135,20 @@ describe('composables', () => {
|
||||
expectTypeOf(useFetch('/test', { default: () => 500 }).data).toMatchTypeOf<Ref<number>>()
|
||||
})
|
||||
|
||||
it('infer request url string literal from server/api routes', () => {
|
||||
// request can accept dynamic string type
|
||||
const dynamicStringUrl:string = 'https://example.com/api'
|
||||
expectTypeOf(useFetch(dynamicStringUrl).data).toMatchTypeOf<Ref<Pick<unknown, never>>>()
|
||||
|
||||
// request param should infer string literal type / show auto-complete hint base on server routes, ex: '/api/hello'
|
||||
expectTypeOf(useFetch('/api/hello').data).toMatchTypeOf<Ref<string>>()
|
||||
expectTypeOf(useLazyFetch('/api/hello').data).toMatchTypeOf<Ref<string>>()
|
||||
|
||||
// request can accept string literal and Request object type
|
||||
expectTypeOf(useFetch('https://example.com/api').data).toMatchTypeOf<Ref<Pick<unknown, never>>>()
|
||||
expectTypeOf(useFetch(new Request('test')).data).toMatchTypeOf<Ref<Pick<unknown, never>>>()
|
||||
})
|
||||
|
||||
it('provides proper type support when using overloads', () => {
|
||||
expectTypeOf(useState('test')).toMatchTypeOf(useState())
|
||||
expectTypeOf(useState('test', () => ({ foo: Math.random() }))).toMatchTypeOf(useState(() => ({ foo: Math.random() })))
|
||||
|
Loading…
Reference in New Issue
Block a user