Open5
Supabase で DB の型情報を自動生成する
Supabase でテーブルの型を生成する
typescript-openapi を利用する
$ npx openapi-typescript https://your-project.supabase.co/rest/v1/?apikey=your-anon-key --output types/supabase.ts
出力されるファイルの中の definitions
にテーブル情報が格納されている
例えば Users テーブルなら以下。not null
を指定していないカラムは optional になる
export interface definitions {
users: {
/**
* Note:
* This is a Primary Key.<pk/>
*/
id: number
username: string
avatar: string
created_at?: string
updated_at?: string
}
}
snake case のカラム名を camel case に変更したい場合、型情報の変更であれば type-fest の CamelCasedPropertiesDeep
を利用すれば良い
なお、DB からの返り値(supabase.from(table).select()
)のオブジェクトのキー名を camel case に変換したい場合、camelcase-keys
を使えばいい。
なお、ネスト内も変換したい場合は、以下のような便利関数を作れば良い
import camelcaseKeys from 'camelcase-keys'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export const camelizeDeeply = <T extends Record<string, any> | readonly any[]>(arg: T) =>
camelcaseKeys(arg, { deep: true })
自動生成した型の扱いを一部公開。
コマンドで generated.ts を生成して型をキャメルケースに変換するだけ。簡単
テーブル名を定数に
//table.ts
export const Table = {
Companies: 'companies',
Beers: 'beers',
Users: 'users',
Reviews: 'reviews',
Comments: 'comments',
ReviewLikes: 'review_likes',
CommentActivities: 'comment_activities',
RelationshipActivities: 'relationship_activities',
} as const
view 名を定数に
export const View = {
// 通知
CommentActivities: 'comment_activities_view',
} as const
自動生成した型。今開発してるサイトでは約3000行のファイルになっている。テーブルの型が自動生成されている。以下は一部
// generated.ts
export interface definitions {
beers: {
/**
* Note:
* This is a Primary Key.<pk/>
*/
id: number;
name: string;
/**
* Note:
* This is a Foreign Key to `brands.id`.<fk table='brands' column='id'/>
*/
brand_id?: number;
description?: string;
purchase_url?: string;
};
// ...
}
// types
import { Session as SupabaseSession, User as SupabaseUser } from '@supabase/supabase-js'
import { CamelCasedPropertiesDeep } from 'type-fest'
import { Table } from '../db'
import { View } from '../views'
import { definitions } from './generated'
// スネークケースをキャメルケースに変換する
type CCD<T> = CamelCasedPropertiesDeep<T>
type R<T> = Required<T>
// Table
export type Beer = CCD<definitions[typeof Table.Beers]>
export type CommentLike = CCD<definitions[typeof Table.CommentLikes]>
export type CommentReply = CCD<definitions[typeof Table.CommentReplies]>
export type Comment = CCD<definitions[typeof Table.Comments]>
export type Review = CCD<definitions[typeof Table.Reviews]>
export type User = CCD<definitions[typeof Table.Users]>
// Enum
export type Taste = definitions[typeof Table.ReviewTaste]['taste']
// View
// 通知系
export type CommentActivitiesView = R<CCD<definitions[typeof View.CommentActivities]>>