-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
refactor(nuxt): enhance useFetch
and useLazyFetch
request type
#4825
Conversation
Enhance the useFetch and useLazyFetch request's type by inferring nitropack's server route's string literal (InternalApi interface). supporting auto-complete and showing type hints.
✅ Deploy Preview for nuxt3-docs ready!
To edit notification comments on pull requests, go to your Netlify site settings. |
…zyFetch` #4823 add type tests to composables suite, calling useFetch with: 1. all routes generated from server, 2. external url, 3. Request object. And should throw type error when pass in invalid request string
One thing that's missing is the ability to type POST request body, is there a way to implement it? |
@Rigo-m I'll look into this! |
Sorry that I can't help, I'm still bad a TS somehow hahaha |
Got a working code that infers the body type of a POST API, but still needs to manually export the type from the API file and change the auto-generated InternalApi interface, or have to make some change to nitropack (and maybe h3) to make the implementation cleaner. hacky method // .nuxt/types/nitro.d.ts
declare module 'nitropack' {
type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T
interface InternalApi {
// turn value of InternalApi in to tuple, with index 1 being the body type
'/api/test': [Awaited<ReturnType<typeof import('../../server/api/test').default>>, import('../../server/api/test').BodyType]
'/__nuxt_error': [Awaited<ReturnType<typeof import('../../../packages/nuxt/src/core/runtime/nitro/renderer').default>>,'']
}
}
// server/api/test.ts
export type BodyType = {tag:string, index:number } // export the manually defined type
export default defineEventHandler(async (event) => {
const body = await useBody<BodyType>(event)
return { result: body.tag }
})
// composable/fetch.ts
export declare type FetchRequestUrl =
Exclude<keyof InternalApi, '/__nuxt_error'>
| (`${string}${'/'|'.'}${string}` & {})
| Exclude<FetchRequest, string>
interface ExFetchOptions<Route extends FetchRequestUrl> extends FetchOptions {
body?: Route extends keyof InternalApi ? InternalApi[Route][1] : FetchOptions['body']
}
export interface UseFetchOptions<
DataT,
ReqT extends FetchRequestUrl,
Transform extends _Transform<DataT, any> = _Transform<DataT, DataT>,
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
> extends AsyncDataOptions<DataT, Transform, PickKeys>, ExFetchOptions<ReqT> {
key?: string
}
// usage
const { data } = useFetch('/api/test', { // have to update nitropack's type to correctly infer data type
method: 'POST',
body: { tag: '3', index: 2 } // body will be type 'BodyType '
}) |
Maybe a clean solution could be manually typing body by extending nuxt schema like we do for manually tiping useRuntimeConfig? |
I love this idea. I think rather than seeking to implement within ... and then update this PR accordingly. WDYT @pi0? |
I also love to try this idea! Indeed nitro seems better place to implement types for |
Sounds great! I implement it in Nuxt first as I wasn't sure if this should be implemented in nitropack. But after some digging and trying to implement type hint for POST body yesterday, I also found out that the codes to updates are mostly in nitropack. mainly:
I'll find some time to dig into it 👍 |
Hey, @danielroe @pi0 would like to get some suggestions/notices (if any) on point 2 before I start, for changing the |
UpdateImplementing this enhancement in |
@didavid61202 Since unjs/nitro#208 is landed, do you mind to rework this PR? Thanks! |
I'm on it! 🚀 |
…-request-url-type
I would hide all |
updated in b49385c, excluding all |
@didavid61202 Maybe we can move this fix directly to Nitro and avoid workaround? I can quickly merge it for nitro and this after that :) |
sure, on it! |
Looking great! There were a couple of workarounds in 7e89fe8 that I think we can now remove as well, if you're up for it 😊 |
Can we directly use |
sure, on it! will see what I can do 👍 |
got it! |
useFetch
and useLazyFetch
request type #4823useFetch
and useLazyFetch
request type #4823
useFetch
and useLazyFetch
request type #4823useFetch
and useLazyFetch
request type
useFetch
and useLazyFetch
request typeuseFetch
and useLazyFetch
request type
Thanks for working on this @didavid61202 @danielroe <3 |
Updates
awaiting fix in nitro for
NitroFetchRequest
type to support string type (FixNitroFetchRequest
type to supportstring
type unjs/nitro#225)update at 2022/5/11
updated this PR according to
unjs/nitro
's newNitroFetchRequest
type (enhance $fetch's request type infer from generated InternalApi interface unjs/nitro#208)update at 2022/5/11
Implementing this enhancement in the
unjs/nitro
repo for$fetch
first (enhance $fetch's request type infer from generated InternalApi interface unjs/nitro#208), and will update this PR accordingly.update at 2022/5/7
Enhance the useFetch and useLazyFetch request's type by inferring nitropack's server route's string literal (InternalApi interface). supporting auto-complete and showing type hints.
🔗 Linked issue
Resolve nuxt/nuxt#13934
❓ Type of change
📚 Description
Enhance the
useFetch
anduseLazyFetch
request's type by inferring nitropack's server route's string literal (InternalApi interface).This will provide better DX and prevent typos while using
useFetch
anduseLazyFetch
by supporting auto-complete and showing type hints when entering the request. And should still be able to pass other valid request URLs likehttps://example.com/api
or Request object likenew Request('/api/test')
Usage scenario
assume project contains
server/api/test.ts
📝 Checklist