Skip to main content

Generating Types

Supabase will soon release native type generators that dump your database types for various languages. For now, we support TypeScript through a third-party tool.

Usage with TypeScript#

supabase-js ships with type definitions for usage with TypeScript and for convenient IntelliSense auto-complete and documentation in your editor.

When using TypeScript, you can pass the type of database row as a type parameter to the from method to get better auto-completion support down the chain. If you don't provide a type for the row you need to explicitly pass from<any>('tableName').

type Message = {  id: number;  inserted_at: string;  message: string;  user_id: string;  channel_id: number;  author: { username: string };}
const response = await supabase  .from<Message>('messages') // Message maps to the type of the row in your database.  .select('*, author:user_id(username)')  .match({ channel_id: 2 }) // Your IDE will be able to help with auto-completion.response.data // Response data will be of type Array<Message>.
// If you don't provide a type for the row you need to explicitly pass `from<any>('tableName')`.const response = await supabase  .from<any>('messages')  .select('*, author:user_id(username)')  .match({ channel_id: 2 })response.data // Response data will be of type Array<any>.

Generate database types from OpenAPI specification#

Supabase generates a OpenAPI specification file for your database which can be used to generate your data types for usage with TypeScript.

The OpenAPI specification for your Supabase project can be accessed as follows:

https://your-project.supabase.co/rest/v1/?apikey=your-anon-key

Using the open source openapi-typescript tool you can generate your types and store them locally:

npx openapi-typescript https://your-project.supabase.co/rest/v1/?apikey=your-anon-key --output types/supabase.ts

Important notes:

  • Since the generator uses JSON API, there is no way to determine if a column is an Array. It will generate array types as string, even though Supabase handles this automatically and returns arrays. You can fix this manually in the files by changing the type, e.g. names: string -> names: string[]
  • The types won't automatically stay in sync with your database, so make sure to regenerate your types after your make changes to your database.

After you have generated your types, you can use them in your TypeScript projects:

import { NextApiRequest, NextApiResponse } from "next";import { createClient } from "@supabase/supabase-js";import { definitions } from "../../types/supabase";
const supabase = createClient(  process.env.NEXT_PUBLIC_SUPABASE_URL,  process.env.SUPABASE_SECRET_KEY);
export default async (req: NextApiRequest, res: NextApiResponse) => {  const allOnlineUsers = await supabase    .from<definitions["users"]>("users")    .select("*")    .eq("status", "ONLINE");  res.status(200).json(allOnlineUsers);};

Update types automatically with GitHub Actions#

One way to keep your type definitions in sync with your database is to set up a GitHub action that runs on a schedule.

Add a script to your package.json to generate the types:

"update-types": "npx openapi-typescript https://your-project.supabase.co/rest/v1/?apikey=your-anon-key --output types/database/index.ts"

In your repo, create the file .github/workflows/update-types.yml. Add the following snippet into this file to define the action. If there is a change to your definitions, this script will commit the change to your repo.

name: Update database types
on:  schedule:    # sets the action to run daily. You can modify this to run the action more or less freqently    - cron: '0 0 * * *'
jobs:  update:    runs-on: ubuntu-latest    steps:      - uses: actions/checkout@v2        with:          persist-credentials: false          fetch-depth: 0      - uses: actions/setup-node@v2.1.5        with:          node-version: 14      - run: npm run update-types      - name: check for file changes        id: git_status        run: |          echo "::set-output name=status::$(git status -s)"      - name: Commit files        if: ${{contains(steps.git_status.outputs.status, ' ')}}        run: |          git add types/database/index.ts          git config --local user.email "41898282+github-actions[bot]@users.noreply.github.com"          git config --local user.name "github-actions[bot]"          git commit -m "Update database types" -a      - name: Push changes        if: ${{contains(steps.git_status.outputs.status, ' ')}}        uses: ad-m/github-push-action@master        with:          github_token: ${{ secrets.GITHUB_TOKEN }}          branch: ${{ github.ref }}