Schema / Types things
I would like to know which would be the ideal pattern to type a schema in convex so it plays well with a typed language like TS or Rescript.
My original idea would be to write the schema, for example:
But then I have two queries in the app that fetch different parts of the customer.
In this case would I need to create an additional type for the response
getCustomerEmail
?10 Replies
@alexcole @ballingt are the experts on Convex schemas + types
@Gorka Cesium to back up a bit, Convex looks for a
schema.ts
file that uses a lets you declare the types of the documents in your database, and then the types flow out from there. https://docs.convex.dev/using/schemasDefining a Schema | Convex Developer Hub
End-to-end type safety requires typing your tables.
This is the really nicely supported flow, it would help to hear what you think of this flow as a jumping off point.
Once you're using
schema.ts
file, the types of queries like getCustomers
and getCustomerEmail
will be inferred; you can even use these types in your codebase like ReturnType<typeof getCustomerEmail>
.sounds convenient. So in my case with Rescript I would have to build a util that generates the
.d.ts
to Rescript types so I can leverage automatic inference
for TS it is taken care by npm convex dev
if i understand correctlyYes that sounds right, and how hard this is depends on some details of Rescript that I'm not familiar with. The "trick" we do with TypeScript is importing the types directly from the modules in the
convex/
directory, so the codegen is very minimal.I see, very cool
That would save me from writing a lot of code
Are you hoping to write your Convex functions in JavaScript, but your frontend in Rescript?
(someday you should be able to write your Convex functions in Rescript too! but right now the bundler is hardcoded in the CLI)
I think i would write as much as possible in Rescript since it transpiles to Js. Except a few functions where the type bindings get too tricky
Would be great to have Rescript as a first class citizen in convex but I understand it might not be a priority due to the small user base
How do you handle the case when you need to write a utility function that takes a param type Customer eg. validateCustomerEmail and you want to use it with the responses of getCustomerName and getCustomerEmail?
I have used a data accesor similar to d3 utils so the type compiler doesn’t complain.
I guess another way to make that param polyvariant but would be a lot of boilerplate
generally, you can't — the return type of getCustomerName and getCustomerEmail are different shapes. I need to learn more about Rescript's type system, but in many languages you could implement an interface that describes objects that have an email field, and pass that into validateCustomerEmail. In TypeScript, you don't need to write the interface except in the function signature.
Nice, maybe there’s something like that. Thanks I’ll look into it