I have a content collection in AstroJs which has a property as an object.
How can i create a Type for this object and reuse it in a component?
The schema:
const blog = defineCollection({
schema: ({ image }) =>
z.object({
title: z.string(),
description: z.string(),
publishDate: z.date(),
observations: z
.array(
z.object({
title: z.string(),
img: image(),
body: z.string(),
})
)
.optional(),
heroImage: image().optional(),
}),
});
The element in the observations should become a Type so that i can reference it in a props Type later: F.e.:
<Cards observations={frontmatter.observations} />
Desired props definition:
export interface Props {
observations: Observation[];
}
I tried with references as described here: https://docs.astro.build/en/guides/content-collections/#defining-collection-references.
But this requires to store the object in seperate files resp. collection.
I would like to have them in the frontmatter of the mdx file directly, like so:
---
title: "title"
description: "some desc."
publishDate: 2022-05-23
observations:
- title: "title 1"
img: "../../assets/img1.jpg"
body: "text"
- title: "title 2"
img: "../../assets/img2.jpg"
body: "text"
---
So how can i have a Type for this nested "observation" element?
Since Astro is using Zod for this, you can do:
import { defineCollection, z, type ImageFunction } from "astro:content";
const getObservationSchema = (image: ImageFunction) =>
z.object({
title: z.string(),
img: image(),
body: z.string(),
})
const blog = defineCollection({
schema: ({ image }) =>
z.object({
title: z.string(),
description: z.string(),
publishDate: z.date(),
observations: z.array(getObservationSchema(image)).optional(),
heroImage: image().optional(),
}),
});
export type Observation = z.infer<ReturnType<typeof getObservationSchema>>