fix(nuxt): add overloads for asyncData generic + default (#22258)

This commit is contained in:
Maik Kowol 2023-07-23 10:24:54 +02:00 committed by GitHub
parent 429d3656e9
commit 7046930a67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 0 deletions

View File

@ -78,6 +78,16 @@ export function useAsyncData<
handler: (ctx?: NuxtApp) => Promise<ResT>, handler: (ctx?: NuxtApp) => Promise<ResT>,
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT> options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null> ): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
export function useAsyncData<
ResT,
DataE = Error,
DataT = ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
DefaultT = DataT,
> (
handler: (ctx?: NuxtApp) => Promise<ResT>,
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
export function useAsyncData< export function useAsyncData<
ResT, ResT,
DataE = Error, DataE = Error,
@ -89,6 +99,17 @@ export function useAsyncData<
handler: (ctx?: NuxtApp) => Promise<ResT>, handler: (ctx?: NuxtApp) => Promise<ResT>,
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT> options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null> ): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
export function useAsyncData<
ResT,
DataE = Error,
DataT = ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
DefaultT = DataT,
> (
key: string,
handler: (ctx?: NuxtApp) => Promise<ResT>,
options?: AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
export function useAsyncData< export function useAsyncData<
ResT, ResT,
DataE = Error, DataE = Error,
@ -267,6 +288,16 @@ export function useLazyAsyncData<
handler: (ctx?: NuxtApp) => Promise<ResT>, handler: (ctx?: NuxtApp) => Promise<ResT>,
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'> options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null> ): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
export function useLazyAsyncData<
ResT,
DataE = Error,
DataT = ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
DefaultT = DataT,
> (
handler: (ctx?: NuxtApp) => Promise<ResT>,
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
export function useLazyAsyncData< export function useLazyAsyncData<
ResT, ResT,
DataE = Error, DataE = Error,
@ -278,6 +309,18 @@ export function useLazyAsyncData<
handler: (ctx?: NuxtApp) => Promise<ResT>, handler: (ctx?: NuxtApp) => Promise<ResT>,
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'> options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null> ): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
export function useLazyAsyncData<
ResT,
DataE = Error,
DataT = ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
DefaultT = DataT,
> (
key: string,
handler: (ctx?: NuxtApp) => Promise<ResT>,
options?: Omit<AsyncDataOptions<ResT, DataT, PickKeys, DefaultT>, 'lazy'>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, DataE | null>
export function useLazyAsyncData< export function useLazyAsyncData<
ResT, ResT,
DataE = Error, DataE = Error,

View File

@ -41,6 +41,19 @@ export function useFetch<
request: Ref<ReqT> | ReqT | (() => ReqT), request: Ref<ReqT> | ReqT | (() => ReqT),
opts?: UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method> opts?: UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, ErrorT | null> ): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, ErrorT | null>
export function useFetch<
ResT = void,
ErrorT = FetchError,
ReqT extends NitroFetchRequest = NitroFetchRequest,
Method extends AvailableRouterMethod<ReqT> = ResT extends void ? 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT> : AvailableRouterMethod<ReqT>,
_ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT,
DataT = _ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
DefaultT = DataT,
> (
request: Ref<ReqT> | ReqT | (() => ReqT),
opts?: UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, ErrorT | null>
export function useFetch< export function useFetch<
ResT = void, ResT = void,
ErrorT = FetchError, ErrorT = FetchError,
@ -136,6 +149,19 @@ export function useLazyFetch<
request: Ref<ReqT> | ReqT | (() => ReqT), request: Ref<ReqT> | ReqT | (() => ReqT),
opts?: Omit<UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>, 'lazy'> opts?: Omit<UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>, 'lazy'>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, ErrorT | null> ): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, ErrorT | null>
export function useLazyFetch<
ResT = void,
ErrorT = FetchError,
ReqT extends NitroFetchRequest = NitroFetchRequest,
Method extends AvailableRouterMethod<ReqT> = ResT extends void ? 'get' extends AvailableRouterMethod<ReqT> ? 'get' : AvailableRouterMethod<ReqT> : AvailableRouterMethod<ReqT>,
_ResT = ResT extends void ? FetchResult<ReqT, Method> : ResT,
DataT = _ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
DefaultT = DataT,
> (
request: Ref<ReqT> | ReqT | (() => ReqT),
opts?: Omit<UseFetchOptions<_ResT, DataT, PickKeys, DefaultT, ReqT, Method>, 'lazy'>
): AsyncData<PickFrom<DataT, PickKeys> | DefaultT, ErrorT | null>
export function useLazyFetch< export function useLazyFetch<
ResT = void, ResT = void,
ErrorT = FetchError, ErrorT = FetchError,

View File

@ -309,6 +309,33 @@ describe('composables', () => {
expectTypeOf(useFetch('/test', { default: () => 500 }).data).toEqualTypeOf<Ref<unknown>>() expectTypeOf(useFetch('/test', { default: () => 500 }).data).toEqualTypeOf<Ref<unknown>>()
}) })
it('correct types when using ResT type-assertion with default function', () => {
// @ts-expect-error default type should match generic type
useFetch<string>('/test', { default: () => 0 })
// @ts-expect-error default type should match generic type
useLazyFetch<string>('/test', { default: () => 0 })
// @ts-expect-error default type should match generic type
useAsyncData<string>(() => $fetch('/test'), { default: () => 0 })
// @ts-expect-error default type should match generic type
useLazyAsyncData<string>(() => $fetch('/test'), { default: () => 0 })
expectTypeOf(useFetch<string>('/test', { default: () => 'test' }).data).toEqualTypeOf<Ref<string>>()
expectTypeOf(useLazyFetch<string>('/test', { default: () => 'test' }).data).toEqualTypeOf<Ref<string>>()
expectTypeOf(useAsyncData<string>(() => $fetch('/test'), { default: () => 'test' }).data).toEqualTypeOf<Ref<string>>()
expectTypeOf(useLazyAsyncData<string>(() => $fetch('/test'), { default: () => 'test' }).data).toEqualTypeOf<Ref<string>>()
// transform must match the explicit generic because of typescript limiations microsoft/TypeScript#14400
expectTypeOf(useFetch<string>('/test', { transform: () => 'transformed' }).data).toEqualTypeOf<Ref<string | null>>()
expectTypeOf(useLazyFetch<string>('/test', { transform: () => 'transformed' }).data).toEqualTypeOf<Ref<string | null>>()
expectTypeOf(useAsyncData<string>(() => $fetch('/test'), { transform: () => 'transformed' }).data).toEqualTypeOf<Ref<string | null>>()
expectTypeOf(useLazyAsyncData<string>(() => $fetch('/test'), { transform: () => 'transformed' }).data).toEqualTypeOf<Ref<string | null>>()
expectTypeOf(useFetch<string>('/test', { default: () => 'test', transform: () => 'transformed' }).data).toEqualTypeOf<Ref<string>>()
expectTypeOf(useLazyFetch<string>('/test', { default: () => 'test', transform: () => 'transformed' }).data).toEqualTypeOf<Ref<string>>()
expectTypeOf(useAsyncData<string>(() => $fetch('/test'), { default: () => 'test', transform: () => 'transformed' }).data).toEqualTypeOf<Ref<string>>()
expectTypeOf(useLazyAsyncData<string>(() => $fetch('/test'), { default: () => 'test', transform: () => 'transformed' }).data).toEqualTypeOf<Ref<string>>()
})
it('infer request url string literal from server/api routes', () => { it('infer request url string literal from server/api routes', () => {
// request can accept dynamic string type // request can accept dynamic string type
const dynamicStringUrl = 'https://example.com/api' const dynamicStringUrl = 'https://example.com/api'