Reputation: 1038
I am fetching data from an API in Nuxt3. I am using typescript and I wish to define the type of data that I will get. How do I specify this?
<script lang="ts" setup>
interface APIBody {
/* properties defined here */
}
const {data} = await useFetch("api_url here")
</script>
<template>
{{ data.name.officialName }}
<template>
I get an error in the template
where I am displaying data.name.officialName
Property 'name' does not exist on type 'never'
However, while running the code in the browser, the website works fine.
Edit I tried the following code but I am receiving a different error now.
<script lang="ts" setup>
interface APIBody {
/* properties defined here */
}
const typedData = ref<APIBody[]>()
const {data} = await useFetch("api_url here")
typedData.value = data as APIBody[] // -> error here
</script>
<template>
{{ data.name.officialName }}
<template>
The error in this case is:
Conversion of type 'Ref<Pick<unknown, never>>' to type 'APIBody[]' may be a mistake because neither type sufficiently overlaps with the other.
Upvotes: 19
Views: 23561
Reputation: 61
It's my working example in Nuxt 3.9.0:
// /api/test.post.ts
export default defineEventHandler(async (event) => {
const body = await readBody(event);
return { body };
});
In any component or page:
<script lang="ts" setup>
import type { AsyncData } from 'nuxt/app';
import type { FetchError } from 'ofetch';
interface Body { key: string };
const { data: { value: { body } }, error } = await useFetch('/api/test', {
method: 'post',
body: {
key: 'value',
}
}) as AsyncData<{ body: Body }, FetchError>;
// now you're getting body's properties without ts-errors
console.log(body.key); // value
</script>
Upvotes: 5
Reputation: 723
If we also need a type based on what is in pick
also, you can check this composable:
type SomeProps = {
prop1: string;
prop2: string;
};
export function usePropsApi() {
const { public: { api } } = useRuntimeConfig();
return {
read: <T extends keyof SomeProps>({
pick = [],
}: {
pick?: Array<T>;
} = {}) => useFetch<Pick<SomeProps, T>>('/props', {
baseURL: api,
...(pick.length && pick),
}),
};
}
and using like this, props other that the ones from pick[]
will be excluded from type:
const { data } = await usePropsApi().read({
pick: ['prop1'],
});
console.log('data.value: ', data.value?.prop1);
console.log('data.value: ', data.value?.prop2); // Property 'prop2' does not exist on type ...
Upvotes: 1
Reputation: 1078
You can give a type to useFetch
to define the return type
Like:
interface APIBody {
/* properties defined here */
}
const {data} = await useFetch<APIBody>("api_url here")
Upvotes: 33