From 32044dc8a5d863077684dd880d134b48c28b0eb4 Mon Sep 17 00:00:00 2001 From: Toby Faux <2037757+tobyfaux@users.noreply.github.com> Date: Thu, 17 Nov 2022 01:27:24 +1100 Subject: [PATCH] fix(nuxt): allow union type arguments for `useAsyncData` (#9061) --- packages/nuxt/src/app/composables/asyncData.ts | 9 ++++++++- test/fixtures/basic/server/api/union.ts | 4 ++++ test/fixtures/basic/types.ts | 10 +++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/basic/server/api/union.ts diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 75d21f30a47..eba8f205a51 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -13,7 +13,14 @@ export type PickFrom> = T extends Array : Pick : T -export type KeysOf = Array +export type KeysOf = Array< + T extends T // Include all keys of union types, not just common keys + ? keyof T extends string + ? keyof T + : string + : never +> + export type KeyOfRes = KeysOf> type MultiWatchSources = (WatchSource | object)[] diff --git a/test/fixtures/basic/server/api/union.ts b/test/fixtures/basic/server/api/union.ts new file mode 100644 index 00000000000..9358a00ecc2 --- /dev/null +++ b/test/fixtures/basic/server/api/union.ts @@ -0,0 +1,4 @@ +export default defineEventHandler(() => ({ + type: 'a', + foo: 'bar' +}) as { type: 'a', foo: string } | { type: 'b', baz: string }) diff --git a/test/fixtures/basic/types.ts b/test/fixtures/basic/types.ts index a73c8738f2c..db32fda10d4 100644 --- a/test/fixtures/basic/types.ts +++ b/test/fixtures/basic/types.ts @@ -17,6 +17,7 @@ describe('API routes', () => { it('generates types for routes', () => { expectTypeOf($fetch('/api/hello')).toEqualTypeOf>() expectTypeOf($fetch('/api/hey')).toEqualTypeOf>() + expectTypeOf($fetch('/api/union')).toEqualTypeOf>() expectTypeOf($fetch('/api/other')).toEqualTypeOf>() expectTypeOf($fetch('/test')).toEqualTypeOf>() }) @@ -25,6 +26,8 @@ describe('API routes', () => { expectTypeOf(useAsyncData('api-hello', () => $fetch('/api/hello')).data).toEqualTypeOf>() expectTypeOf(useAsyncData('api-hey', () => $fetch('/api/hey')).data).toEqualTypeOf>() expectTypeOf(useAsyncData('api-hey-with-pick', () => $fetch('/api/hey'), { pick: ['baz'] }).data).toEqualTypeOf>() + expectTypeOf(useAsyncData('api-union', () => $fetch('/api/union')).data).toEqualTypeOf>() + expectTypeOf(useAsyncData('api-union-with-pick', () => $fetch('/api/union'), { pick: ['type'] }).data).toEqualTypeOf>() expectTypeOf(useAsyncData('api-other', () => $fetch('/api/other')).data).toEqualTypeOf>() expectTypeOf(useAsyncData('api-generics', () => $fetch('/test')).data).toEqualTypeOf>() @@ -34,6 +37,8 @@ describe('API routes', () => { expectTypeOf(useLazyAsyncData('lazy-api-hello', () => $fetch('/api/hello')).data).toEqualTypeOf>() expectTypeOf(useLazyAsyncData('lazy-api-hey', () => $fetch('/api/hey')).data).toEqualTypeOf>() expectTypeOf(useLazyAsyncData('lazy-api-hey-with-pick', () => $fetch('/api/hey'), { pick: ['baz'] }).data).toEqualTypeOf>() + expectTypeOf(useLazyAsyncData('lazy-api-union', () => $fetch('/api/union')).data).toEqualTypeOf>() + expectTypeOf(useLazyAsyncData('lazy-api-union-with-pick', () => $fetch('/api/union'), { pick: ['type'] }).data).toEqualTypeOf>() expectTypeOf(useLazyAsyncData('lazy-api-other', () => $fetch('/api/other')).data).toEqualTypeOf>() expectTypeOf(useLazyAsyncData('lazy-api-generics', () => $fetch('/test')).data).toEqualTypeOf>() @@ -45,6 +50,8 @@ describe('API routes', () => { expectTypeOf(useFetch('/api/hello').data).toEqualTypeOf>() expectTypeOf(useFetch('/api/hey').data).toEqualTypeOf>() expectTypeOf(useFetch('/api/hey', { pick: ['baz'] }).data).toEqualTypeOf>() + expectTypeOf(useFetch('/api/union').data).toEqualTypeOf>() + expectTypeOf(useFetch('/api/union', { pick: ['type'] }).data).toEqualTypeOf>() expectTypeOf(useFetch('/api/other').data).toEqualTypeOf>() expectTypeOf(useFetch('/test').data).toEqualTypeOf>() @@ -54,7 +61,8 @@ describe('API routes', () => { expectTypeOf(useLazyFetch('/api/hello').data).toEqualTypeOf>() expectTypeOf(useLazyFetch('/api/hey').data).toEqualTypeOf>() expectTypeOf(useLazyFetch('/api/hey', { pick: ['baz'] }).data).toEqualTypeOf>() - expectTypeOf(useLazyFetch('/api/other').data).toEqualTypeOf>() + expectTypeOf(useLazyFetch('/api/union').data).toEqualTypeOf>() + expectTypeOf(useLazyFetch('/api/union', { pick: ['type'] }).data).toEqualTypeOf>() expectTypeOf(useLazyFetch('/api/other').data).toEqualTypeOf>() expectTypeOf(useLazyFetch('/test').data).toEqualTypeOf>()