fix(nuxt): infer useFetch method when generic is passed (#20797)

This commit is contained in:
Gypsophyllite 2023-05-17 19:56:47 +08:00 committed by GitHub
parent 2b10dd7b75
commit f39eb6e981
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 11 additions and 4 deletions

View File

@ -31,7 +31,7 @@ export function useFetch<
ResT = void, ResT = void,
ErrorT = FetchError, ErrorT = FetchError,
ReqT extends NitroFetchRequest = NitroFetchRequest, ReqT extends NitroFetchRequest = NitroFetchRequest,
Method extends AvailableRouterMethod<ReqT> = 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT>, Method extends AvailableRouterMethod<ReqT> = ResT extends void ? 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT> : AvailableRouterMethod<ReqT>,
_ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT, _ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT,
DataT = _ResT, DataT = _ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT> PickKeys extends KeysOf<DataT> = KeysOf<DataT>
@ -43,7 +43,7 @@ export function useFetch<
ResT = void, ResT = void,
ErrorT = FetchError, ErrorT = FetchError,
ReqT extends NitroFetchRequest = NitroFetchRequest, ReqT extends NitroFetchRequest = NitroFetchRequest,
Method extends AvailableRouterMethod<ReqT> = 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT>, Method extends AvailableRouterMethod<ReqT> = ResT extends void ? 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT> : AvailableRouterMethod<ReqT>,
_ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT, _ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT,
DataT = _ResT, DataT = _ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT> PickKeys extends KeysOf<DataT> = KeysOf<DataT>
@ -124,7 +124,7 @@ export function useLazyFetch<
ResT = void, ResT = void,
ErrorT = FetchError, ErrorT = FetchError,
ReqT extends NitroFetchRequest = NitroFetchRequest, ReqT extends NitroFetchRequest = NitroFetchRequest,
Method extends AvailableRouterMethod<ReqT> = 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT>, Method extends AvailableRouterMethod<ReqT> = ResT extends void ? 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT> : AvailableRouterMethod<ReqT>,
_ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT, _ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT,
DataT = _ResT, DataT = _ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT> PickKeys extends KeysOf<DataT> = KeysOf<DataT>
@ -136,7 +136,7 @@ export function useLazyFetch<
ResT = void, ResT = void,
ErrorT = FetchError, ErrorT = FetchError,
ReqT extends NitroFetchRequest = NitroFetchRequest, ReqT extends NitroFetchRequest = NitroFetchRequest,
Method extends AvailableRouterMethod<ReqT> = 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT>, Method extends AvailableRouterMethod<ReqT> = ResT extends void ? 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT> : AvailableRouterMethod<ReqT>,
_ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT, _ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT,
DataT = _ResT, DataT = _ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT> PickKeys extends KeysOf<DataT> = KeysOf<DataT>

View File

@ -0,0 +1,3 @@
export default defineEventHandler(() => ({
method: 'post' as const
}))

View File

@ -17,6 +17,7 @@ describe('API routes', () => {
expectTypeOf($fetch('/api/hello')).toEqualTypeOf<Promise<string>>() expectTypeOf($fetch('/api/hello')).toEqualTypeOf<Promise<string>>()
expectTypeOf($fetch('/api/hey')).toEqualTypeOf<Promise<{ foo: string, baz: string }>>() expectTypeOf($fetch('/api/hey')).toEqualTypeOf<Promise<{ foo: string, baz: string }>>()
expectTypeOf($fetch('/api/hey', { method: 'get' })).toEqualTypeOf<Promise<{ foo: string, baz: string }>>() expectTypeOf($fetch('/api/hey', { method: 'get' })).toEqualTypeOf<Promise<{ foo: string, baz: string }>>()
expectTypeOf($fetch('/api/hey', { method: 'post' })).toEqualTypeOf<Promise<{ method: 'post' }>>()
// @ts-expect-error not a valid method // @ts-expect-error not a valid method
expectTypeOf($fetch('/api/hey', { method: 'patch ' })).toEqualTypeOf<Promise<{ foo: string, baz: string }>>() expectTypeOf($fetch('/api/hey', { method: 'patch ' })).toEqualTypeOf<Promise<{ foo: string, baz: string }>>()
expectTypeOf($fetch('/api/union')).toEqualTypeOf<Promise<{ type: 'a', foo: string } | { type: 'b', baz: string }>>() expectTypeOf($fetch('/api/union')).toEqualTypeOf<Promise<{ type: 'a', foo: string } | { type: 'b', baz: string }>>()
@ -51,8 +52,10 @@ describe('API routes', () => {
it('works with useFetch', () => { it('works with useFetch', () => {
expectTypeOf(useFetch('/api/hello').data).toEqualTypeOf<Ref<string | null>>() expectTypeOf(useFetch('/api/hello').data).toEqualTypeOf<Ref<string | null>>()
expectTypeOf(useFetch('/api/hey').data).toEqualTypeOf<Ref<{ foo: string, baz: string } | null>>() expectTypeOf(useFetch('/api/hey').data).toEqualTypeOf<Ref<{ foo: string, baz: string } | null>>()
// @ts-expect-error TODO: remove when fixed upstream: https://github.com/unjs/nitro/pull/1247
expectTypeOf(useFetch('/api/hey', { method: 'GET' }).data).toEqualTypeOf<Ref<{ foo: string, baz: string } | null>>() expectTypeOf(useFetch('/api/hey', { method: 'GET' }).data).toEqualTypeOf<Ref<{ foo: string, baz: string } | null>>()
expectTypeOf(useFetch('/api/hey', { method: 'get' }).data).toEqualTypeOf<Ref<{ foo: string, baz: string } | null>>() expectTypeOf(useFetch('/api/hey', { method: 'get' }).data).toEqualTypeOf<Ref<{ foo: string, baz: string } | null>>()
expectTypeOf(useFetch('/api/hey', { method: 'post' }).data).toEqualTypeOf<Ref<{ method: 'post' } | null>>()
// @ts-expect-error not a valid method // @ts-expect-error not a valid method
useFetch('/api/hey', { method: 'PATCH' }) useFetch('/api/hey', { method: 'PATCH' })
expectTypeOf(useFetch('/api/hey', { pick: ['baz'] }).data).toEqualTypeOf<Ref<{ baz: string } | null>>() expectTypeOf(useFetch('/api/hey', { pick: ['baz'] }).data).toEqualTypeOf<Ref<{ baz: string } | null>>()
@ -60,6 +63,7 @@ describe('API routes', () => {
expectTypeOf(useFetch('/api/union', { pick: ['type'] }).data).toEqualTypeOf<Ref<{ type: 'a' } | { type: 'b' } | null>>() expectTypeOf(useFetch('/api/union', { pick: ['type'] }).data).toEqualTypeOf<Ref<{ type: 'a' } | { type: 'b' } | null>>()
expectTypeOf(useFetch('/api/other').data).toEqualTypeOf<Ref<unknown>>() expectTypeOf(useFetch('/api/other').data).toEqualTypeOf<Ref<unknown>>()
expectTypeOf(useFetch<TestResponse>('/test').data).toEqualTypeOf<Ref<TestResponse | null>>() expectTypeOf(useFetch<TestResponse>('/test').data).toEqualTypeOf<Ref<TestResponse | null>>()
expectTypeOf(useFetch<TestResponse>('/test', { method: 'POST' }).data).toEqualTypeOf<Ref<TestResponse | null>>()
expectTypeOf(useFetch('/error').error).toEqualTypeOf<Ref<FetchError | null>>() expectTypeOf(useFetch('/error').error).toEqualTypeOf<Ref<FetchError | null>>()
expectTypeOf(useFetch<any, string>('/error').error).toEqualTypeOf<Ref<string | null>>() expectTypeOf(useFetch<any, string>('/error').error).toEqualTypeOf<Ref<string | null>>()