Specifying Postgres table as T prop?

Hello, I am trying to implement a reusable data fetching function. I need to specify a table in the function parameters. How can I specify the table type on T? I currently have PgTable, but it seems to throw a ts error:
async function paginatedSearchQuery<T extends PgTable>({
ctx,
table,
limit = 10,
cursor = 0,
searchQuery,
searchField,
orderBy
}: {
ctx: ApiContextProps;
table: T;
limit?: number;
cursor?: number;
searchQuery?: string;
searchField?: any;
orderBy?: any;
}) {
const take = limit + 1;
const offset = cursor || 0;

// Build the query with pagination
let query = ctx.db.select().from(table).limit(take).offset(offset).$dynamic();
async function paginatedSearchQuery<T extends PgTable>({
ctx,
table,
limit = 10,
cursor = 0,
searchQuery,
searchField,
orderBy
}: {
ctx: ApiContextProps;
table: T;
limit?: number;
cursor?: number;
searchQuery?: string;
searchField?: any;
orderBy?: any;
}) {
const take = limit + 1;
const offset = cursor || 0;

// Build the query with pagination
let query = ctx.db.select().from(table).limit(take).offset(offset).$dynamic();
Ideally I would like for the returning data to be typed. The error is: Argument of type 'T' is not assignable to parameter of type 'TableLikeHasEmptySelection<T> extends true ? DrizzleTypeError<"Cannot reference a data-modifying statement subquery if it doesn't contain a returning clause"> : T'. Type 'PgTable<TableConfig>' is not assignable to type 'TableLikeHasEmptySelection<T> extends true ? DrizzleTypeError<"Cannot reference a data-modifying statement subquery if it doesn't contain a returning clause"> : T'.ts(2345)
3 Replies
RWOverdijk
RWOverdijk7d ago
@gapped I do not have the answer, but I have been trying to do this as well and the way the typing works in drizzle makes this very difficult. If you find an answer please let me know. I just want a generic findMany with pagination and a total count. Closest I got was removing the extends PgTable and using table as PgTable in the from().
gapped
gappedOP7d ago
Fair enough, it makes sense that drizzle types make this difficult.
Levitybot
Levitybot6d ago
From my testing Drizzle just doesn't like and kind of generic typing/base repo (maybe someone knows better than me). Plan B: Instead of writing a reusable base repo with a generic type etc. write a base repo generator script that generates an individual strongly typed base repo for every table, and a primary repo for each table that extends it. The base repos are always replaced when re-generated, the primary repos are only created if they don't already exist. This means you can add custom content/functions to the primary repos. This setup gives you the same time saving of a base repo, but everything is always strongly typed, no generics, less complexity.

Did you find this page helpful?