Astro กับ TypeScript: Type Safety ใน Astro Projects

#astro13 เม.ย. 2569

TypeScript ใน Astro

Astro รองรับ TypeScript ตั้งแต่ต้น ทุก .astro file สามารถใช้ TypeScript ใน frontmatter ได้เลย

ตั้งค่า tsconfig.json

{
  "extends": "astro/tsconfigs/strict",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@components/*": ["src/components/*"],
      "@layouts/*": ["src/layouts/*"],
      "@utils/*": ["src/utils/*"]
    }
  }
}

Type Props

---
interface Props {
  title: string;
  description?: string;
  tags: string[];
  pubDate: Date;
  author: {
    name: string;
    avatar: string;
  };
}

const { title, description, tags, pubDate, author } = Astro.props;
---

<article>
  <h1>{title}</h1>
  {description && <p>{description}</p>}
  <time>{pubDate.toLocaleDateString('th-TH')}</time>
</article>

Type Astro.locals

// src/env.d.ts
/// <reference types="astro/client" />

declare namespace App {
  interface Locals {
    user?: {
      id: string;
      name: string;
      email: string;
      role: 'admin' | 'user';
    };
    session?: {
      id: string;
      expiresAt: Date;
    };
  }
}

Type API Routes

// src/pages/api/users.ts
import type { APIRoute } from 'astro';

interface User {
  id: number;
  name: string;
  email: string;
}

export const GET: APIRoute = async ({ locals }) => {
  const users: User[] = await fetchUsers();
  return new Response(JSON.stringify(users), {
    headers: { 'Content-Type': 'application/json' }
  });
};

export const POST: APIRoute = async ({ request }) => {
  const body: Partial<User> = await request.json();
  // validation...
  return new Response(null, { status: 201 });
};

Type Content Collections

import { z, defineCollection } from 'astro:content';

const blog = defineCollection({
  schema: z.object({
    title: z.string(),
    pubDate: z.date(),
    tags: z.array(z.enum(['astro', 'typescript', 'react']))
  })
});

// Type ถูก infer อัตโนมัติ
const posts = await getCollection('blog');
const firstPost = posts[0];
firstPost.data.title; // string ✅
firstPost.data.pubDate; // Date ✅

สรุป

TypeScript ใน Astro ทำงานได้ดีมาก ทั้ง props, locals, API routes และ content collections มี type safety เต็มรูปแบบ ช่วยลด bug ได้มากครับ