What are the Drizzle conventions for giving names to Drizzle return types?
Hello all, I have a question about Drizzle conventions. Do people give names to the return types of their Drizzle calls?
For example, consider the following code:
- Here, we use the
ReturnType
utility type from TypeScript to satisfy DRY. (If we wanted to violate DRY, we could repeat all the user fields inside of a dedicated User
TypeScript interface
.)
- However, we now have a problem where Intellisense does not work properly. In other words, if we mouse over user
in the following code:
We get the full enumerated object inside of a union with undeifned
, instead of the much easier to read and understand User | undefined
.
Does anyone know if there are Drizzle conventions to get smarter Intellisense here?23 Replies
you can use
I would create a explicit type and export it. Then use that type as the return type of the get function
Ok, thanks. It just kind of sucks because user has like 20 fields and now I have to duplicate everything, violating DRY, and since they are separated the two things can get out of sync, i.e. the manually created interface can have excess fields.
You don't need to explicitely create the type
Oh. Can you show an example?
I'm guessing you already have a
User
type in your schema like this:
I don't already have that, no. That inferSelect is a nice trick.
You can use that type and do:
Ah, right. So that's slightly better than doing:
In that I'm only repeating the names of the fields, instead of both the names of the fields and the types of the fields.
But I still have to duplicate 20+ names inside of the Pick.
Maybe the type anotation should be
Promise<PartialUser[]>
, you can check it
As long as you are partially selecting the user
I wonder why your type there is not getting properly picked upWhat do you mean?
This one
Um
It is "properly" being picked up, it just is ugly, because its a union of like 20+ different things and destroys the mouseover.
And you can't manually annotate the
get
function as returning User[]
because TypeScript complains that you can't have recursive types.
If that doesn't make sense I can try to explain betterNo I get it. You're attempting to define a type using it's own definition
Can you show a screenshot of the type you are getting?
The problem is that you have a lot of columns?
@Angelelz That's the type, but just imagine with 20+ fields instead of 3.
What I want is to have
User | undefined
, which makes it much easier to reason about, and so that it matches the name of the variable (user
).I thought you weren't getting you type correctly
There's nothing you can do if you're inferring the type
How is typescript supposed to know that that type is called User?
Right, which is exactly the premise of my question.
I was envisioning something like setting up the shape of the SELECT call beforehand, such that the type interference can be stored in a
User
type, and then during runtime inside of the actual get
function I can re-use the SELECT schema.
Is something like that possible?
(The inferSelect
is a nice trick though that gets me half of the way there at least.)Yeah, I mean, people usually complain about the opposite, seeing
User | undefined
but wanting to see the keys.
There is no other way, you either infer the type and get the keys explicitly or use the $inferSelect
type helper in combination with Omit
or Pick
utility types to anotate the return type of your function
Now, if you were not selecting a partial table, maybe typescript would give you the User type, but I'm not sure
No, maybe not, because how would it know that it's called UserYeah, I mean, people usually complain about the opposite, seeing User | undefined but wanting to see the keys.Oh, that's ironic, lol I can't convert the OP to
findFirst
because it has a where
clause, right?You can use a where in a findFirst
you can use where in query
ah, thanks
to be honest i think i'll just stick with the normal sql code, its easier to read and one less layer of abstraction