5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Astro の Content Collections で動的ルーティングを実装するときの型指定

Posted at

この記事の概要

Astro のバージョン 2 で追加された Content Collections において動的ルーティングを実装したら型のエラーが出たので調べました。

主に自分の備忘録のための記事です。

環境

Astro のバージョンは 2.10.7 です。

公式ドキュメントの記載

公式ドキュメントの example コードを引用します。

src/pages/posts/[...slug].astro
---
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 から分割代入した entryany になっています。

遭遇した問題

記事の中の frontmatterkeywords という要素を用意していて、型は string の配列にしていました。
そして、書いていたコードはこちらです。

<ul>
  {entry.data.keywords.map((keyword) => <li>{keyword}</li>)}
</ul>

entryany になっているので、keywordany になり得るとのことでエラーが出ています。

解決策

公式ドキュメントの TypeScript のセクションに書いてありました。

src/pages/posts/[...slug].astro
---
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; }
---

InferGetStaticParamsTypeInferGetStaticPropsType を指定することで、Astro.paramsAstro.props に型を当てられました。

先ほどの keyword からもエラーが消えました。

最後に

Astro は割と TypeScript が前提になっている感じだと思っていたのですが、予期せぬエラーが出たときは TypeScript 🚀 Astro Documentation に目を通すのが良さそうです。


最後まで読んでくださってありがとうございます!
X (Twitter)でも情報を発信しているので、良かったらフォローお願いします!

Devトークでお話してくださる方も募集中です!

  1. 型は src/content/config.ts というファイルの中に指定することで有効になります。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?