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 ได้มากครับ