Type-Safe Supabase Queries
--
Generate TypeScript types from your Supabase database and get full type inference for queries.
Generate types:
npx supabase gen types typescript --project-id YOUR_PROJECT_ID > src/types/database.types.tsCreate typed client:
import { createClient } from '@supabase/supabase-js';import type { Database } from '../types/database.types';
export const supabase = createClient<Database>( import.meta.env.PUBLIC_SUPABASE_URL, import.meta.env.PUBLIC_SUPABASE_ANON_KEY);
// Now all queries are type-safe!Type-safe queries:
// ✅ TypeScript knows the shape of 'posts'const { data, error } = await supabase .from('posts') .select('id, title, content, author_id, created_at') .eq('published', true);
if (data) { data[0].title; // ✅ Type: string data[0].published; // ✅ Type: boolean data[0].fake_column; // ❌ Type error!}
// ✅ Joins are typed tooconst { data: postsWithAuthor } = await supabase .from('posts') .select(` id, title, author:users(name, email) `);
if (postsWithAuthor) { postsWithAuthor[0].author.name; // ✅ Typed!}
// ✅ Inserts validate against schemaconst { data: newPost } = await supabase .from('posts') .insert({ title: 'New Post', content: 'Content here', published: true, // fake_field: 'invalid' // ❌ Type error! }) .select() .single();Helper for better inference:
import { supabase } from './supabase';import type { Database } from '../types/database.types';
type Tables = Database['public']['Tables'];
// Type-safe table accessorexport function table<T extends keyof Tables>(tableName: T) { return supabase.from(tableName);}
// Usage:const posts = await table('posts').select('*');const users = await table('users').select('id, name');Auto-complete and validation:
// IDE auto-completes column namesconst { data } = await supabase .from('posts') .select('id, ti') // ← Auto-completes to 'title' .eq('publ') // ← Auto-completes to 'published' .single();
// Enforces correct typesawait supabase.from('posts').insert({ title: 'Valid', published: 'yes', // ❌ Type error: expected boolean});Benefits:
- Catch typos at compile time
- Auto-completion for all columns
- Type-safe joins and relationships
- Refactoring confidence
- No runtime overhead