なつねこメモ

主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ 書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。

Contentful JavaScript SDK を TypeScript で使いたい

いまさら JavaScript なんて書けるか!ということで、 Contentful JavaScript SDK を TypeScript で使います。 まずはライブラリのインストール:

$ pnpm add contentful

いれたあと、以下のようにライブラリを定義すると良い。

import contentful from "contentful";

const contentfulClient = contentful.createClient({
  space: import.meta.env.CONTENTFUL_SPACE_ID,
  accessToken: import.meta.env.DEV
    ? import.meta.env.CONTENTFUL_PREVIEW_TOKEN
    : import.meta.env.CONTENTFUL_DELIVERY_TOKEN,
  host: import.meta.env.DEV ? "preview.contentful.com" : "cdn.contentful.com",
});

export { contentfulClient };

基本、あとは contentfulClient に生えているメソッドを使えば良いが、各エントリーについて型定義が欲しい。
そういった場合、一定の規則に従った型定義を作成する必要がある。

具体的には、以下の型定義と互換性がある必要がある。

type FieldsType = Record<string, any>;

type EntrySkeletonType<Fields extends FieldsType = FieldsType, Id = string> = {
  fields: Fields;
  contentTypeId: Id;
};

これだけみてもさっぱりなので、ここは非公式ライブラリで自動生成するのが良い。
ということで、以下のコマンドを実行する。

$ pnpm dlx cf-content-types-generator -s SPACE_ID  -t CFPAT-XXXX --v10

SPACE_ID には、型定義を生成したい Contentful のスペース ID を、 CFPAT-XXXX には、 Content Management Token を設定する。
ここでしか使わないと思うので、該当トークンは使ったら破棄して良い。
また、 --v10 フラグは、 Contentful SDK のバージョンが v10 以降の場合に指定する必要がある。
いま普通にインストールすると、v10.1.6 あたりがインストールされるはずなので、この場合は指定する必要がある。

コマンドを実行すると、以下のような型定義が生成されるはず。

import type {
  ChainModifiers,
  Entry,
  EntryFieldTypes,
  EntrySkeletonType,
  LocaleCode,
} from "contentful";

export interface TypeArticleFields {
  title: EntryFieldTypes.Symbol;
  slug: EntryFieldTypes.Symbol;
  body: EntryFieldTypes.RichText;
  published_at: EntryFieldTypes.Date;
}

export type TypeArticleSkeleton = EntrySkeletonType<
  TypeArticleFields,
  "article"
>;
export type TypeArticle<
  Modifiers extends ChainModifiers,
  Locales extends LocaleCode
> = Entry<TypeArticleSkeleton, Modifiers, Locales>;

これのうち、 TypeArticleSkeletongetEntries の型引数として渡すと良い。

// こんな感じ
const entries = await contentfulClient.getEntries<ArticleSkeleton>({
  content_type: "article",
});

ということで、メモでした。