React Native Expo プロジェクトが既にセットアップしていて、@apollo/client を使って、useQuery や gql を使用してGraphQLのデータを取得するコードが動作していました。そこからGraphQLで取得したデータの型を自動生成する方法を学んだので記録として残します。
必要なパッケージのインストール
まず、GraphQL の型自動生成ツール graphql-code-generator
とそのプラグインをインストールします。
npm install --save-dev @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations graphql
codegen.yml の設定
プロジェクトのルートに codegen.yml
ファイルを作成し、次のように設定します。このファイルには、GraphQL スキーマから型を生成するための設定が記載されています。
codegen.yml
overwrite: true
schema: "https://example.com/graphql" # GraphQL API のエンドポイント
documents: "app/**/*.tsx" # GraphQLクエリが含まれるファイルのパス
generates:
types/graphql.ts: # 型ファイルの出力先
plugins:
- "typescript" # TypeScript型を生成
- "typescript-operations" # クエリやミューテーションに基づく型を生成
graphql.d.ts ファイルの設置
graphql.d.ts
は、.graphql
ファイルをインポートしたときに TypeScript が正しく認識できるようにするための型定義ファイルです。
プロジェクトのルートに graphql.d.ts
というファイルを作成します。
以下のコードを graphql.d.ts
に追加します。
declare module "*.graphql" {
import { DocumentNode } from "graphql";
const value: DocumentNode;
export default value;
}
このファイルにより、.graphql
ファイルを TypeScript が認識できるようになります。なお、.graphql
ファイルを直接使わずに gql
タグでクエリを定義する場合、この設定は不要です。
tsconfig.json の設定
graphql.d.ts
ファイルを tsconfig.json
に追加して、TypeScript がこのファイルを認識できるように設定します。
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
},
"include": [
"app/**/*.tsx",
"graphql.d.ts", // graphql.d.ts ファイルを追加
"types/graphql.ts" // 型生成ファイルのパス
]
}
codegen スクリプトの設定
package.json
に codegen
スクリプトを追加
まず、package.json
の scripts
セクションに codegen
コマンドを追加して、型生成を簡単に実行できるようにします。
{
"scripts": {
"codegen": "graphql-codegen" // `codegen` スクリプトを追加
}
}
型生成の実行
ここまで設定が整ったら、以下のコマンドで型ファイルを生成します。
npm run codegen
実行後、設定した types/graphql.ts
に生成された型が追加されているはずです。
生成された型を使って型安全にデータを取得する
生成された型を使用することで、クエリの結果を型安全に扱うことができます。以下は、その具体的な使用例です。
import { gql, useQuery } from "@apollo/client";
import { GetPostsQuery, GetPostsQueryVariables } from "../types/graphql";
const GET_POSTS = gql`
query GetPosts($first: Int) {
posts(first: $first) {
nodes {
id
title
content
}
}
}
`;
export default function PostsScreen() {
const { loading, error, data } = useQuery<GetPostsQuery, GetPostsQueryVariables>(GET_POSTS, {
variables: { first: 5 },
});
if (loading) return <Text>Loading...</Text>;
if (error) return <Text>Error: {error.message}</Text>;
return (
<View>
{data?.posts?.nodes.map(post => (
<Text key={post.id}>{post.title}</Text>
))}
</View>
);
}
これで、Expo環境でも型安全な GraphQL データの取得が可能になり、開発がさらに効率化されるはずです。