Extracting `useFetch` return type

Is there a better way of extracting the type my server route is returning from a route in vue side of the app? When I do
const { data } = useFetch('/api/public/metadata')
// data is globalThis.Ref<{ someComplicated: type; withMany: properties }> | undefined
const { data } = useFetch('/api/public/metadata')
// data is globalThis.Ref<{ someComplicated: type; withMany: properties }> | undefined
nuxt is aware of what my server route returns and correctly types the data. But I want to get the type a route returns somewhere else. For example to be used in a component defineProps if a parent was doing the fetching and component is expecting to receive it
defineProps<{
fromApi: complicated_type_fetched_in_parent
>()
defineProps<{
fromApi: complicated_type_fetched_in_parent
>()
without having to manually retype it. I got to
type Tmp = UnwrapRef<Awaited<ReturnType<typeof useFetch<void, Error, `/api/public/:language`>>>['data']>;
type Tmp = UnwrapRef<Awaited<ReturnType<typeof useFetch<void, Error, `/api/public/:language`>>>['data']>;
and it works I guess but properties of Tmp are all wrapped in SerializeObject<>, like
type Tmp = {
meta: SerializeObject<Record<string, string>>[] | undefined;
}
type Tmp = {
meta: SerializeObject<Record<string, string>>[] | undefined;
}
Everything still works, Tmp['meta'] will be Record<string, string>[] but I'm wondering if there's a simpler way
2 Replies
kapa.ai
kapa.ai5w ago
Hi @asasinmode. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- Based on the knowledge sources provided, there isn't a straightforward or officially documented way to extract the exact return type from a useFetch call in Nuxt 3 without the SerializeObject wrapper. However, I can provide some insights and a potential workaround based on the information available. The SerializeObject wrapper is likely related to how Nuxt handles serialization of data between the server and client. As mentioned in the Data Fetching documentation, Nuxt uses devalue for serialization, which allows for transferring more complex data types. A potential workaround to get a cleaner type without the SerializeObject wrapper could be to use a custom type assertion. Here's an example of how you might do this:
type UnwrappedApiResponse<T> = T extends SerializeObject<infer U> ? U : T;

type ApiResponseType = UnwrapRef<Awaited<ReturnType<typeof useFetch<void, Error, `/api/public/:language`>>>['data']>;

type CleanApiResponseType = {
[K in keyof ApiResponseType]: UnwrappedApiResponse<ApiResponseType[K]>
};

defineProps<{
fromApi: CleanApiResponseType
}>();
type UnwrappedApiResponse<T> = T extends SerializeObject<infer U> ? U : T;

type ApiResponseType = UnwrapRef<Awaited<ReturnType<typeof useFetch<void, Error, `/api/public/:language`>>>['data']>;

type CleanApiResponseType = {
[K in keyof ApiResponseType]: UnwrappedApiResponse<ApiResponseType[K]>
};

defineProps<{
fromApi: CleanApiResponseType
}>();
This approach creates a utility type UnwrappedApiResponse that removes the SerializeObject wrapper, and then applies it to each property of the original response type. It's worth noting that this is not an official solution, and it may not work perfectly in all cases. The Nuxt team is aware of type-related issues and is working on improvements. For instance, there's ongoing work to improve type safety in routing, as mentioned in this YouTube video on type-safe routing in Nuxt. For the most up-to-date and accurate information on handling types with useFetch, it's recommended to check the latest Nuxt documentation or ask in the Nuxt community forums. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai5w ago
<@282178759204012032> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?