DT
Drizzle Teamā€¢16mo ago
JT

how do you pass a query in a typesafe way?

Let's say i want to paginate a query, so I'm going to pass a query such as this to a pagination function
db.select().from(users).where(like(users.email, '%@gmail.com'))
db.select().from(users).where(like(users.email, '%@gmail.com'))
And then that pagination function will add .limit() and .offset() to the query. What type would I put on the function argument?
9 Replies
bloberenober
bloberenoberā€¢16mo ago
That's a tough one, let me investigate and get back to you. Alright, so here's how it might look like:
import type { JoinNullability, SelectMode } from 'drizzle-orm/pg-core/query-builders/select.types';

function withPagination<
TTableName extends string,
TSelection,
TSelectMode extends SelectMode,
TExcludedMethods extends string,
TNullabilityMap extends Record<string, JoinNullability>,
>(qb: PgSelect<TTableName, TSelection, TSelectMode, TExcludedMethods, TNullabilityMap>) {
return qb.offset(10).limit(10);
}

const qb = db.select().from(users);
const result = await withPagination(qb);
import type { JoinNullability, SelectMode } from 'drizzle-orm/pg-core/query-builders/select.types';

function withPagination<
TTableName extends string,
TSelection,
TSelectMode extends SelectMode,
TExcludedMethods extends string,
TNullabilityMap extends Record<string, JoinNullability>,
>(qb: PgSelect<TTableName, TSelection, TSelectMode, TExcludedMethods, TNullabilityMap>) {
return qb.offset(10).limit(10);
}

const qb = db.select().from(users);
const result = await withPagination(qb);
The key thing here is to copy all the PgSelect generics to the function, so that TS can figure out how to properly infer the function result type. I had to change the internal types a bit to make it work, so this code won't work right now, because I need to release a new ORM version with updated types. I'll do that right away and let you know once it's done.
JT
JTā€¢16mo ago
holy hell that's a lot of boilerplate!
bloberenober
bloberenoberā€¢16mo ago
Yeah šŸ˜… Our types are quite complex, so unfortunately that means you have to understand that complexity if you need to operate on them
JT
JTā€¢16mo ago
it's ok, i'll learn it. its just a lot šŸ™‚
Andrii Sherman
Andrii Shermanā€¢16mo ago
With your feedback we can improve a library more and more. So maybe at some point of time those type will be smaller
bloberenober
bloberenoberā€¢16mo ago
@plainblackguy sorry about the holdup on this one. It turned out our types were not really intended for such use cases, so they need to be changed more than planned initially. We're currently discussing the best approach we should take to support this case.
JT
JTā€¢16mo ago
Iā€™m OK waiting a little. Thank you for the update.
bloberenober
bloberenoberā€¢16mo ago
@plainblackguy I've implemented the fix and published it as drizzle-orm@beta. Now you can just write the function you need like this:
function withPagination<T extends AnyPgSelect>(qb: T) {
return qb.offset(10).limit(10);
}
function withPagination<T extends AnyPgSelect>(qb: T) {
return qb.offset(10).limit(10);
}
JT
JTā€¢16mo ago
sweet!