Inferring full Typescript types from schema?
Hi friends! Trying out Convex for the first time (looks quite slick!), trying to migrate an existing NextJS app currently using vercel/postgres + Drizzle.
Two questions so far:
1. It looks like there's no Date or timestamp data type? My current models have created/updated/viewed times. _creationTime is great, but if I wanted to add the others, should I use int/float myself? Is creationTime in UTC?
2. How can I infer the full TypeScript type of a schema object? E.g. if I do this, it's missing the _id/_creationTime system fields.
7 Replies
1. Yes there isn't a built-in Date type. I'd recommend doing something like
_creationTime
does, which is milliseconds since epoch (UTC)
2. You have one quick way to get the type of a document, which is the Doc<'users'>
type. If you want to make a validator that includes the _id and _creationTime, lmk. I made a little helper in the ai-town repo I can point to
For dates, I find storing a utc string or timestamp, and a separate named timezone to be more reliable than translating between dates with and without timezones, or date strings that capture a UTC offset rather than the timezone name, since the offset changes throughout the year b/c of daylight savings, etc.
ISO 8601 / RFC 3339 support string comparison and are more readable, so I prefer those over default Date formatting.
(new Date()).toISOString()
and
new Date(isoString)
make this easyThanks!
1) Sounds good! Ok to use a v.number() for this, or should it be v.int64()?
2) Perfect, that's what I was looking for. I skimmed the Typescript docs earlier and didn't see anything, but now see the
Doc
type mentioned there.
I also use enum types quite a big in zod/Drizzle. I don't see any native enum type in Convex. Should I just do this?
2. that's right.
1. as long as you don't mind having floats in your database (you don't need large integers, you won't be sharing these with other systems via streaming export anytime soon), I'd recommend you just use v.number(). we'll have betters support for JS numbers that are actually meant to be ints via some orm-like stuff in the near future
but v.int64() will make your app have to deal with bigints all the time, which is a pain in the ass
Got it, will stick with number, thanks!
This is resolved, and works fine. But one minor nit is timestamps aren't rendered as dates in the dashboard (I guess _creationTime is special cased). Not a big deal, but maybe something that would help usability a bit.
Yep thanks for the feedback!
Times are now rendered as dates for other fields, and zod validators can be used for function argument validation, output validation, and (if you read the caveats in the article) schema definition: https://stack.convex.dev/typescript-zod-function-validation
Using Zod with TypeScript for Server-side Validation and End-to-End...
Use Zod with TypeScript for argument validation on your server functions allows you to both protect against invalid data, and define TypeScript types ...