TypeScript Types
Generate a types file from your database and use it to catch column name mistakes before they reach users.
Why First: The Mistake That Costs 20 Minutes
You're building the fee payment confirmation page. You write:
You save the file. You run the app. The fee page loads — but the paid date is blank. You check the network tab. The data is coming back. You add a console.log. You stare at the output for several minutes. You're looking for paidAt in the response. It isn't there.
Eventually — maybe 20 minutes later — you realize: the column is called paid_at, not paidAt. Snake case, not camel case. A one-character difference, caught half an hour after you made the mistake.
Excel equivalent: You type =SUMIF(ClientsTable[Clint_Name], ...) — a typo in a column reference. Excel shows #NAME? immediately. You fix it in 5 seconds.
TypeScript types do the same thing for database column names. VS Code underlines paidAt in red the moment you type it, before you save, before you run anything. The mistake costs 5 seconds to fix instead of 20 minutes to debug.
What the Types File Is
When you run:
Supabase reads your entire database schema and generates a TypeScript file that describes it precisely.
A simplified version of what it produces:
This file is machine-generated and precise. Every column that exists in your database appears here with its exact name and data type. Every column that doesn't exist is absent — which is how VS Code can immediately catch paidAt (doesn't appear in the types) vs paid_at (does appear).
Never edit this file manually. It is entirely regenerated every time you run the gen types command. Any manual changes will be overwritten. If you need to add custom types, create a separate file — for example, src/lib/custom-types.ts.
Adding Types to Your Supabase Client
Once the database.types.ts file exists, update your Supabase client to use it:
That one change — createClient<Database> instead of createClient — activates full type safety across your entire project. Every query you write from this point forwards knows the shape of your database.
How It Looks in Practice
With types active, VS Code gives you:
Autocomplete on table names:
Autocomplete on column names:
Immediate error on wrong column names:
Type-safe data access:
Using Row Types Directly
Sometimes you need to describe the shape of a fee record in your own code — for example, a component that receives a fee record as a prop. Instead of writing the type yourself (and risking it going out of sync), extract it from the generated types:
Now if you rename paid_at to payment_date in your database and regenerate the types, every place in your code that uses feeRecord.paid_at immediately shows a red underline. You find every usage, update them all, and ship with confidence.
Excel analogy: Named ranges in Excel. Instead of referencing G3:G52 everywhere, you name it ClientRevenue. Every formula that uses ClientRevenue updates automatically when the data range changes. TypeScript row types are named references to your database columns — they update across your entire codebase when the source changes.
The Insert and Update Types
The generated types have three variants for each table:
| Variant | Used for | What's different |
|---|---|---|
Row | Reading data (SELECT) | All columns present, required types as-is |
Insert | Writing new rows (INSERT) | Auto-generated columns (id, created_at) become optional |
Update | Modifying existing rows (UPDATE) | All columns optional — you only include what's changing |
When to Regenerate
Every time you change your database schema, regenerate the types. Make it a reflex:
| You did this | Do this immediately after |
|---|---|
| Added a new table | supabase gen types typescript --project-id REF > src/lib/database.types.ts |
| Added a column | Same |
| Renamed a column | Same |
| Changed a column's type | Same |
| Deleted a column | Same |
| Added an enum value | Same |
If you forget, VS Code will not tell you — it works with the last generated types. Your new column won't autocomplete, and code that references the old column name won't immediately error (because the types still say it exists). Regenerate before writing code that touches the changed table.
Shortcut: Create a script in your package.json so you don't have to type the full command every time:
Then just run:
The Full Picture: How Types Flow Through Your Project
In the Udyogaseva production codebase, the types file is at src/lib/database.types.ts and is regenerated every time the schema changes. You can look at that file as a reference — it shows what a real multi-table production schema looks like as TypeScript types.