🌱

【TypeScript × Supabase】自動生成された型を扱いやすくする

2023/08/19に公開

Supabaseは型情報を自動生成してくれる!

公式のドキュメントZennの記事で紹介されているように、
Supabaseは、データベースの型情報を生成するコマンドを提供してくれている。(便利!)

npx supabase gen types typescript --project-id "$PROJECT_REF" --schema public > types/supabase.ts

それにどのような問題が?

ただし、自動生成されたものをそのまま使うとなると、少〜しだけ困る点がある。

それは、全体の型情報から欲しい型情報を取得するまでに、いくつかの階層を掘っていく必要があるという点だ。これは、GithubのDiscussionsにも議題として挙げられている。

例えば、データベースにprofilesテーブル(ユーザのプロフィール情報を格納するテーブル)があったとする。その場合、自動生成されるコードは以下のような構造となる。

export interface Database {
  public: {
    Tables: {
      profiles: {
        Row: {
          avatar_url: string | null;
          id: string;
          updated_at: string | null;
          username: string | null;
        };
        Insert: {
          avatar_url?: string | null;
          id: string;
          updated_at?: string | null;
          username?: string | null;
        };
        Update: {
          avatar_url?: string | null;
          id?: string;
          updated_at?: string | null;
          username?: string | null;
        };
        Relationships: [
         // (省略)
        ];
      };
     // (省略)
    };
  };
}

ここから「profileテーブル全体の型情報が欲しい」となった場合、
以下のようにいくつかの階層を跨いだ上で、型情報を抽出することになる。

import { Database } from '...'
type profile = Database['public']['Tables']['profiles']['Row'];

これが少〜しだけ手間だよね、というのが今回の記事で取り上げたかった問題点である。

解決策

このあたりの問題を解決してくれるのが、better-supabase-typesライブラリだ。
以下のコマンドで、型情報を抽出した上でファイルを上書きし、型の扱いを簡単にしてくれる。

# 1.通常通り、型情報を生成する
npx supabase gen types typescript --project-id "$PROJECT_REF" --schema public > types/supabase.ts

# 2.ライブラリを用いて、生成されたものを上書きする
npx better-supabase-types -i types/supabase.ts -f

これにより、以下の通り記述量を減らすことができる。

# これまで
import { Database } from '...'
type profile = Database['public']['Tables']['profiles']['Row'];

# ライブラリ導入後
import { Profile } from '...'
type profile = Profile;

おわりに

少し違和感を感じていた部分を解消してくれたライブラリでした。
公式がどうしてあのような形で自動生成されるようにしているかは、気になるところですね。

どなたかの作業の助けになれば幸いです。

Discussion