この記事の概要
Astro のバージョン 2 で追加された Content Collections において動的ルーティングを実装したら型のエラーが出たので調べました。
主に自分の備忘録のための記事です。
環境
Astro のバージョンは 2.10.7 です。
公式ドキュメントの記載
公式ドキュメントの example コードを引用します。
---
import { getCollection } from 'astro:content';
// 1. Generate a new path for every collection entry
export async function getStaticPaths() {
const blogEntries = await getCollection('blog');
return blogEntries.map(entry => ({
params: { slug: entry.slug }, props: { entry },
}));
}
// 2. For your template, you can get the entry directly from the prop
const { entry } = Astro.props;
const { Content } = await entry.render();
---
<h1>{entry.data.title}</h1>
<Content />
このとき、getStaticPaths()
の中の entry
は型が指定されています1が
Astro.props
から分割代入した entry
は any
になっています。
遭遇した問題
記事の中の frontmatter
に keywords
という要素を用意していて、型は string
の配列にしていました。
そして、書いていたコードはこちらです。
<ul>
{entry.data.keywords.map((keyword) => <li>{keyword}</li>)}
</ul>
entry
が any
になっているので、keyword
も any
になり得るとのことでエラーが出ています。
解決策
公式ドキュメントの TypeScript のセクションに書いてありました。
---
import { InferGetStaticParamsType, InferGetStaticPropsType, GetStaticPaths } from 'astro';
export const getStaticPaths = (async () => {
const posts = await getCollection('blog');
return posts.map((post) => {
return {
params: { slug: post.slug },
props: { draft: post.data.draft, title: post.data.title },
};
});
}) satisfies GetStaticPaths;
type Params = InferGetStaticParamsType<typeof getStaticPaths>;
type Props = InferGetStaticPropsType<typeof getStaticPaths>;
const { slug } = Astro.params as Params;
// ^? { slug: string; }
const { title } = Astro.props;
// ^? { draft: boolean; title: string; }
---
InferGetStaticParamsType
や InferGetStaticPropsType
を指定することで、Astro.params
や Astro.props
に型を当てられました。
先ほどの keyword
からもエラーが消えました。
最後に
Astro は割と TypeScript が前提になっている感じだと思っていたのですが、予期せぬエラーが出たときは TypeScript 🚀 Astro Documentation に目を通すのが良さそうです。
最後まで読んでくださってありがとうございます!
X (Twitter)でも情報を発信しているので、良かったらフォローお願いします!
Devトークでお話してくださる方も募集中です!
-
型は src/content/config.ts というファイルの中に指定することで有効になります。 ↩