The gist of it is that calling select on a Supabase project will get you back an array of any as the data property of the response. If you were able to pass your own type when calling from('table'), then you'd get back a response where the data property would be an array of that type. You can certainly create these types manually, but that is error prone. The Supabase team is currently working on a solution to generate the types automatically from your database schema, but meanwhile they have a temporary solution, which consists in using the openapi-typescript NPM package to introspect the OpenAPI specification generated from your database schema. In this tutorial we're going to explore the solution provided by the Supabase team, and expand on it to make it more easily usable.
If you want to follow along, you can create a new Supabase project and execute the above SQL in the SQL Editor. Note that since our goal is to explore the types, we're not dealing with Row-Level security and associated policies here: they don't affect the generated types.
With this schema created, we can now generate the types using openapi-typescript. To do this, we need to have the URL of our Supabase project, as well as the anon-key. These can be found under the Settings > API section of Supabase Studio. Armed with these two values, execute the following command in your terminal:
After a few seconds, you'll have a new file called generated-types.ts in the directory where you executed the command. If you open this file, you'll find that the types generated contain more than what we need for the purposes of this tutorial. They contain types for API paths, parameters, and others. The types of interest to us are defined under the definitions interface, and they look like this:
Having to type from every time we want to query a post is verbose. To help with this, we can define our own types. Rather than work in the generated-types.ts file, let's create our own types.ts module. This way, as we change our schema and re-generate the types, our own code won't be overwritten.
What would be the return type of such a query? We'd still get posts, but each post would have an array of comments associated to it. We can easily compose the types we have so far and create a PostWithComments type like this:
What more, nothing is preventing us from selecting columns that don't exist in the database. As our schema is changing and our app is getting larger, it would be nice if the newly generated types could warn us of these things.
I hope you found the methods described above to be useful to you. If anything, the examples I've used should inspire you to build your own types and functions on top of the Supabase client to make your application more robust, type-safe, and easier to write and read.
While Supabase has proved to be that superhero that we open-source enthusiasts have been expecting to chase the commercial villains away?, this post is not to dig deep into Supabase but to understand the various data types in Supabase. As with SQL, most of the data types are similar as seen in the pictures below:
df19127ead