Supabase で簡単 & 便利に!データベーススキーマから TypeScript 型定義を自動生成する方法
✅ 前提条件
- Supabase にてプロジェクトを作成済み
- ちなみに筆者はnextjsの公式チュートリアルで作成したRSC(react server components)アプリケーションにsuparbaseを導入しました
- このチュートリアルのchapter6あたりでsuparbaseのデータベース作成ができます
- テーブル定義はチュートリアル内で作成したものをそのまま使用しております
Supabase CLI を使用して、データベーススキーマから TypeScript の型定義を自動生成する手順を紹介します。
🔥 Supabase とは?
その前にそもそもSupabaseとは何か、簡単に記載します。
Supabase は、オープンソースの Firebase 代替サービスであり、PostgreSQL をベースバックエンドサービスを提供します。以下のような特徴があります。
- 認証、データベース管理、ストレージ、リアルタイム機能を提供。
- クライアントサイドから直接 SQL クエリを実行可能。
- TypeScript との相性が良く、自動型定義生成機能を備えている。
- 詳細は公式サイトを参照してください 👉 Supabase 公式サイト
🚀 1. Supabase CLI のインストール
まず、最新の Supabase CLI をインストールします(最新バージョンについては公式サイトを参照してください)。
まず、最新の Supabase CLI をインストールします。
npm i supabase@">=1.8.1" --save-dev
🔑 2. Supabase へのログイン
Supabase CLI を使用するために、ログインを行います。
npx supabase login
このコマンドを実行すると、ブラウザが自動的に開き、認証コードが表示されます。そのコードをコピーし、ターミナルに貼り付けることでログインが完了します。
🛠 3. プロジェクトの初期化
次に、Supabase プロジェクトを初期化します。
npx supabase init
このコマンドを実行する際、Docker が起動していないとエラーになります。必ず Docker を立ち上げた状態で実行してください。
(例)筆者はMacを使用しているので、Docker Desktop for mac を使用して起動しました。
📌 4. TypeScript の型定義を生成
以下のコマンドを実行し、データベーススキーマに基づいた TypeScript の型定義を生成します。
npx supabase gen types typescript --project-id "$PROJECT_REF" --schema public > database.types.ts
ここで、$PROJECT_REF
には Supabase プロジェクトの ID を指定します。プロジェクト ID は、以下のような URL で XXX
に相当する部分です。
https://supabase.com/dashboard/project/XXX
🔍 5. 生成された TypeScript 型定義の確認
コマンドの実行が成功すると、database.types.ts
ファイルが作成されます。以下のような型定義が含まれていれば、正常に生成されています。
export type Json =
| string
| number
| boolean
| null
| { [key: string]: Json | undefined }
| Json[];
export type Database = {
public: {
Tables: {
customers: {
Row: {
email: string;
id: string;
image_url: string;
name: string;
};
Insert: {
email: string;
id?: string;
image_url: string;
name: string;
};
Update: {
email?: string;
id?: string;
image_url?: string;
name?: string;
};
Relationships: [];
};
invoices: {
Row: {
amount: number;
customer_id: string;
date: string;
id: string;
status: string;
};
Insert: {
amount: number;
customer_id: string;
date: string;
id?: string;
status: string;
};
Update: {
amount?: number;
customer_id?: string;
date?: string;
id?: string;
status?: string;
};
Relationships: [
{
foreignKeyName: "invoices_customer_id_fkey";
columns: ["customer_id"];
isOneToOne: false;
referencedRelation: "customers";
referencedColumns: ["id"];
}
];
};
};
Views: {};
Functions: {};
Enums: {};
CompositeTypes: {};
};
};
このように Row
, Insert
, Update
などの型が適切に生成されていれば、型定義の生成が正しく行われています。
🎯 6. 型定義の使用例
生成された型定義をプロジェクトで活用する方法を紹介します。
database.types.ts
のインポート
import { Database } from '@/database.types';
createServerClient
で型を適用
createServerClient<Database>()
このようにすることで、Supabase のデータベーススキーマを型安全に利用できます。
例
import { Database } from '@/database.types';
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export async function createClient() {
const cookieStore = await cookies()
return createServerClient<Database>(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
getAll() {
return cookieStore.getAll()
},
setAll(cookiesToSet) {
try {
cookiesToSet.forEach(({ name, value, options }) =>
cookieStore.set(name, value, options)
)
} catch {
// The `setAll` method was called from a Server Component.
// This can be ignored if you have middleware refreshing
// user sessions.
}
},
},
}
)
}
revenue
に自動生成された型が反映されている例
export async function fetchRevenue() {
try {
const supabase = await createClient();
const { data: revenue } = await supabase.from('revenue').select('*');
return revenue ?? [];
} catch (error) {
console.error('Database Error:', error);
throw new Error('Failed to fetch revenue data.');
}
}
ちなみにrevenueテーブルのスキーマは下記です。うまくtsの型定義が作成されてますね。
🎉 まとめ
この手順を実行することで、Supabase のデータベーススキーマに基づいた型定義を TypeScript で利用できるようになります。
データベース定義から型が自動生成されるのは便利ですね😊
ぜひ試してみてください!
Discussion