I want to display the products after fetching them and everything works fine but I have some error with TS in the destructuring statement.
Here is my fetching function:
export async function fetchAllProducts() {
try {
const res = await axios.get(url);
const data = res.data;
return {
data
}
} catch(err) {
if(err instanceof AxiosError)
return {
error: err.message
}
}
}
And then I use it in a server component:
export default async function StorePage() {
const { data, error }: Products = await fetchAllProducts(); //the problem is in this line (data and error are underlined)
return (
<section className='section'>
<div className='section__inner'>
<h4 className='section__title'>Products</h4>
{error && <span>{error}</span>}
{!data && !error && <span>loading...</span>}
<div className='section__content products-container'>
{!error && data && data?.length > 0 && data.map((product: ProductProps) => <ProductCard key = {product.id} {...product}/>)}
</div>
</div>
</section>
)
}
When I destructure I get this error:
Type ‘{ data: any; error?: undefined; } | { error: string; data?:
undefined; } | undefined’ is not assignable to type ‘Products’. Type
‘undefined’ is not assignable to type ‘Products’.
Here are my types:
export type Products = {
data: ProductProps[] | null;
error: string | undefined;
}
export type ProductProps = {
id: string;
title: string;
category: string;
description: string;
image: string;
price: number;
rating: {
rate: number,
count: number
}
}
So, I was wondering if the problem was connected to the fetch function, should I add types there or is there another issue?
2
Answers
The issue is with your
catch
function, since ifif(err instanceof AxiosError)
condition does not fulfill,fetchAllProducts
function will returnundefined
.You should add a fallback
{}
return.Typescript demo
In
the
data
property has either to be aProductProps[]
ornull
. But in case of an error duringfetchAllProducts
the result of
fetchAllProducts
will beie, no
data
, iedata == undefined
which is not allowed in a valid instance of theProducts
type … Change the return value in case of an exception toAlso in your
Products
, theerror
is a mandatory property, ie it can have the value ofundefined
but it has to exist. If you want it to be optional, define yourProducts
as followsSee this Playground to see the difference.
Furthermore, you should also consider, what happens if
err
is not anAxiosError
. Then yourfetchAllProducts
won’t return anything and you will try to destructure a value ofundefined
, which will throw a runtime error.