從製作照片牆來理解types.ts 與 content.config.ts的功能及角色差異
Written by
Published on: Sun Jul 05
在製作照片牆的時候,出現一個之前製作部落格文章的時候沒有用過的檔案: type.ts
從內容看起來兩個長得很類似,所以搞不太清楚他們在製作過程中的用途差異,就問了一下AI,以下就整理一下結論。
可以想成 「入境檢查」跟「公司員工證」,這兩個比喻通常很好理解。
每一篇 Markdown 都像一個旅客。
---title: Sunsetimage: /sunset.jpgtags: [travel, sea]---當 Astro 讀取它時,會先經過 content.config.ts。
它會問:「有沒有 title?」、「image 是字串嗎?」、「tags 是不是陣列?」 如果不符合,就不讓它進來(編譯錯誤)。 所以它的工作只有一句話:檢查資料是否合法。
以實際製作流程來說,沒有在content.config.ts輸入相關資料,絕對會報錯。(有點像是建立資料庫的規則)
資料通過檢查後,開始在你的程式裡流動。 例如:
Gallery.astro │ ▼GalleryClient │ ▼GalleryCard這些元件彼此約定: 「我收到的圖片物件長這樣。」
interface GalleryItem { id: string title: string image: string tags: string[]}這就是 types.ts 的工作。 它不是檢查 Markdown,而是讓元件知道: 「我要接收這種資料。」
一張圖看懂
Markdown │ ▼content.config.ts「檢查格式」 │ ▼資料合法 │ ▼types.ts「告訴程式:接下來都用這種型別」 │ ▼GalleryClient │ ▼GalleryCard很多小型 Astro 專案其實可以完全不寫 types.ts
但當你開始做:
export interface GalleryItem { id: string; title: string; image: string; tags: string[];}所有元件都引用同一份定義,就不用每個檔案都重寫一次,也比較容易維護。
答案是:兩個都會用到,但用途不同。 假設你的照片都有標籤:
---title: Sunsettags: - travel - sea---例如:
schema: z.object({ title: z.string(), tags: z.array(z.string()),})它負責檢查:
例如:
export interface GalleryItem { id: string; title: string; tags: string[];}因為 GalleryClient、TagFilter、GalleryCard 都會用到 tags。 例如:
const filteredImages = images.filter(image => image.tags.includes(selectedTag));如果 GalleryItem 沒有定義 tags,TypeScript 就會提示錯誤。 所以它負責的是程式怎麼使用 tags。
用你的資料流來看
Markdown │ ▼content.config.ts「tags 一定要存在,而且是 string[]」 │ ▼getCollection() │ ▼map → GalleryItem ▲ │ types.ts「GalleryItem 有 tags:string[]」 │ ▼GalleryClient │ ├── TagFilter ├── useState(selectedTag) └── filter(images) │ ▼GalleryGrid可以看到:
所以 Tag Filter 的功能本身,比較偏向 types.ts,因為它是在程式裡操作 GalleryItem 的 tags 欄位;而 content.config.ts 則是確保這個欄位一開始就存在且格式正確。