JavaScript: TypeScript support | Supabase Docs (original) (raw)
- Introduction
- Installing
- Initializing
- TypeScript support
- Database
- Fetch data
- Insert data
- Update data
- Upsert data
- Delete data
- Call a Postgres function
- Using filters
- Column is equal to a value
- Column is not equal to a value
- Column is greater than a value
- Column is greater than or equal to a value
- Column is less than a value
- Column is less than or equal to a value
- Column matches a pattern
- Column matches a case-insensitive pattern
- Column is a value
- Column is in an array
- Column contains every element in a value
- Contained by value
- Greater than a range
- Greater than or equal to a range
- Less than a range
- Less than or equal to a range
- Mutually exclusive to a range
- With a common element
- Match a string
- Match an associated value
- Don't match the filter
- Match at least one filter
- Match the filter
- Using modifiers
- Return data after inserting
- Order the results
- Limit the number of rows returned
- Limit the query to a range
- Set an abort signal
- Retrieve one row of data
- Retrieve zero or one row of data
- Retrieve as a CSV
- Override type of successful response
- Partially override or replace type of successful response
- Using explain
- Auth
- Overview
- Create a new user
- Listen to auth events
- Create an anonymous user
- Sign in a user
- Sign in with ID Token
- Sign in a user through OTP
- Sign in a user through OAuth
- Sign in a user through SSO
- Sign out a user
- Send a password reset request
- Verify and log in through OTP
- Retrieve a session
- Retrieve a new session
- Retrieve a user
- Update a user
- Retrieve identities linked to a user
- Link an identity to a user
- Unlink an identity from a user
- Send a password reauthentication nonce
- Resend an OTP
- Set the session data
- Exchange an auth code for a session
- Start auto-refresh session (non-browser)
- Stop auto-refresh session (non-browser)
- Auth MFA
- Enroll a factor
- Create a challenge
- Verify a challenge
- Create and verify a challenge
- Unenroll a factor
- Get Authenticator Assurance Level
- Auth Admin
- Retrieve a user
- List all users
- Create a user
- Delete a user
- Send an email invite link
- Generate an email link
- Update a user
- Delete a factor for a user
- Edge Functions
- Invokes a Supabase Edge Function.
- Realtime
- Subscribe to channel
- Unsubscribe from a channel
- Unsubscribe from all channels
- Retrieve all channels
- Broadcast a message
- Storage
- Create a bucket
- Retrieve a bucket
- List all buckets
- Update a bucket
- Delete a bucket
- Empty a bucket
- Upload a file
- Download a file
- List all files in a bucket
- Replace an existing file
- Move an existing file
- Copy an existing file
- Delete files in a bucket
- Create a signed URL
- Create signed URLs
- Create signed upload URL
- Upload to a signed URL
- Retrieve public URL
- Misc
- Release Notes
supabase-js
has TypeScript support for type inference, autocompletion, type-safe queries, and more.
With TypeScript, supabase-js
detects things like not null
constraints and generated columns. Nullable columns are typed as T | null
when you select the column. Generated columns will show a type error when you insert to it.
supabase-js
also detects relationships between tables. A referenced table with one-to-many relationship is typed as T[]
. Likewise, a referenced table with many-to-one relationship is typed as T | null
.
Generating TypeScript Types
supabase gen types typescript --project-id abcdefghijklmnopqrst > database.types.ts
These types are generated from your database schema. Given a table public.movies
, the generated types will look like:
create table public.movies (
id bigint generated always as identity primary key,
name text not null,
data jsonb null
);
export type Json = string | number | boolean | null | { [key: string]: Json | undefined } | Json[]
export interface Database {
public: {
Tables: {
movies: {
Row: { // the data expected from .select()
id: number
name: string
data: Json | null
}
Insert: { // the data to be passed to .insert()
id?: never // generated columns must not be supplied
name: string // `not null` columns with no default must be supplied
data?: Json | null // nullable columns can be omitted
}
Update: { // the data to be passed to .update()
id?: never
name?: string // `not null` columns are optional on .update()
data?: Json | null
}
}
}
}
}
Using TypeScript type definitions
You can supply the type definitions to supabase-js
like so:
import { createClient } from '@supabase/supabase-js'
import { Database } from './database.types'
const supabase = createClient<Database>(
process.env.SUPABASE_URL,
process.env.SUPABASE_ANON_KEY
)
Helper types for Tables and Joins
You can use the following helper types to make the generated TypeScript types easier to use.
Sometimes the generated types are not what you expect. For example, a view's column may show up as nullable when you expect it to be not null
. Using type-fest, you can override the types like so:
export type Json = // ...
export interface Database {
// ...
}
import { MergeDeep } from 'type-fest'
import { Database as DatabaseGenerated } from './database-generated.types'
export { Json } from './database-generated.types'
// Override the type for a specific column in a view:
export type Database = MergeDeep<
DatabaseGenerated,
{
public: {
Views: {
movies_view: {
Row: {
// id is a primary key in public.movies, so it must be `not null`
id: number
}
}
}
}
}
>
You can also override the type of an individual successful response if needed:
// Partial type override allows you to only override some of the properties in your results
const { data } = await supabase.from('countries').select().overrideTypes<Array<{ id: string }>>()
// For a full replacement of the original return type use the `{ merge: false }` property as second argument
const { data } = await supabase
.from('countries')
.select()
.overrideTypes<Array<{ id: string }>, { merge: false }>()
// Use it with `maybeSingle` or `single`
const { data } = await supabase.from('countries').select().single().overrideTypes<{ id: string }>()
The generated types provide shorthands for accessing tables and enums.
import { Database, Tables, Enums } from "./database.types.ts";
// Before 😕
let movie: Database['public']['Tables']['movies']['Row'] = // ...
// After 😍
let movie: Tables<'movies'>
Response types for complex queries
supabase-js
always returns a data
object (for success), and an error
object (for unsuccessful requests).
These helper types provide the result types from any query, including nested types for database joins.
Given the following schema with a relation between cities and countries, we can get the nested CountriesWithCities
type:
create table countries (
"id" serial primary key,
"name" text
);
create table cities (
"id" serial primary key,
"name" text,
"country_id" int references "countries"
);
import { QueryResult, QueryData, QueryError } from '@supabase/supabase-js'
const countriesWithCitiesQuery = supabase
.from("countries")
.select(`
id,
name,
cities (
id,
name
)
`);
type CountriesWithCities = QueryData<typeof countriesWithCitiesQuery>;
const { data, error } = await countriesWithCitiesQuery;
if (error) throw error;
const countriesWithCities: CountriesWithCities = data;