ข้ามไปยังเนื้อหา

TypeScript & Content Types

Astro มาพร้อม TypeScript support ในตัว — เขียนไฟล์ .ts, type component script และได้ type-checking ใน editor โดยไม่ต้องตั้งอะไร โปรเจกต์ใหม่ extend preset ตัวหนึ่งของ Astro ใน tsconfig.json:

{
"extends": "astro/tsconfigs/strict"
}

preset มี base, strict และ strictest — เลือก strict (หรือ strictest) สำหรับโปรเจกต์จริง เพราะเปิด check ที่จับ bug ได้จริง

คุณ type props ของ component ด้วยการประกาศ interface Props ใน frontmatter แล้ว Astro จะใช้ interface นี้ type-check ทุกที่ที่ component ถูกใช้:

---
interface Props {
title: string;
count?: number; // optional prop
}
const { title, count = 0 } = Astro.props;
---
<h1>{title} ({count})</h1>

ส่ง type ผิดหรือลืม prop ที่จำเป็น editor (และ astro check) จะเตือนที่จุดเรียกใช้

ตรงนี้แหละที่ typing ของ Astro โดดเด่น เมื่อคุณ define content collection ด้วย Zod schema (จากโมดูล content) Astro generate TypeScript type จาก schema นั้น getCollection และ getEntry จะคืน entry ที่มี type ครบ — editor รู้ทุก field ใน frontmatter และ type ของตัวเอง:

import { getCollection } from 'astro:content';
const posts = await getCollection('blog');
// posts[0].data.title -> string (from the schema)
// posts[0].data.pubDate -> Date (z.coerce.date())
// posts[0].data.nope -> type error: property does not exist
flowchart LR
  schema["Zod schema in src/content.config.ts"] --> gen["Astro generates types"]
  gen --> query["getCollection / getEntry return typed data"]
  query --> safe["type errors on wrong field access"]
schema กลายเป็น type ของคุณ

type เหล่านี้อยู่ในโฟลเดอร์ .astro/ ที่ generate ให้ ซึ่ง Astro ดูแลให้เอง (refresh โดย dev server และ astro sync) คุณไม่ต้องแก้เอง แค่ได้ autocomplete และความปลอดภัยฟรีจาก schema ที่คุณเขียนไว้แล้ว

เมื่อใช้ middleware แนบข้อมูลระดับ request (เช่น user ปัจจุบัน) ไว้ที่ Astro.locals คุณกำหนด type ให้ locals ด้วยการประกาศ interface App.Locals มักอยู่ใน src/env.d.ts:

src/env.d.ts
declare namespace App {
interface Locals {
user: { id: string; name: string } | null;
}
}

ตอนนี้ Astro.locals.user มี type ทุกที่ — ใน middleware, page และ endpoint

editor type-check ให้ระหว่างเขียน แต่ไฟล์ .astro ไม่ถูก check โดย tsc คำสั่งที่ทำคือ astro check — validate type ข้ามไฟล์ .astro, .ts และ .tsx ต่อคำสั่งนี้เข้ากับ build เพื่อให้ type error หยุด deploy ที่พัง:

{
"scripts": {
"build": "astro check && astro build"
}
}
type props ของ component ใน Astro ยังไง?
type ของ `getCollection('blog')` มาจากไหน?
type ข้อมูลที่แนบไว้ที่ `Astro.locals` (เช่นโดย middleware) ยังไง?
`astro check` ทำอะไร?