Generic base repository abstract class
So, I’m trying to create a base repository class to extend based on my schema definitions, thing is I’m having trouble getting the types to work, here is my example
import type { InferSelectModel, SQL } from 'drizzle-orm';
import type { AnyPgTable } from 'drizzle-orm/pg-core';
import type { DB, DBTransaction } from './client';
export interface RepositoryOptions {
db?: DB;
tx?: DBTransaction;
}
/**
* A generic base repository class for Drizzle ORM
*
* Note: This implementation uses type assertions in some places to work
* around limitations in TypeScript's ability to fully type the Drizzle ORM.
* The public API is fully typed, but internal implementations may use 'any'.
*/
export class BaseRepository<
TTable extends AnyPgTable,
TSelect = InferSelectModel<TTable>,
> {
protected table: TTable;
protected db: DB | DBTransaction;
constructor(table: TTable, db: DB | DBTransaction) {
this.table = table;
this.db = db;
}
/**
* Find all records matching the given criteria
*/
async findAll(
options: {
limit?: number;
offset?: number;
orderBy?: SQL<unknown>;
where?: SQL<unknown>;
} = {},
): Promise<TSelect[]> {
const { limit, offset, orderBy, where } = options;
// Using any to avoid complex type issues with the query builder
let query = this.db.select().from(this.table).$dynamic();
if (where) {
query = query.where(where);
}
if (orderBy) {
query = query.orderBy(orderBy);
}
if (limit) {
query = query.limit(limit);
}
if (offset) {
query = query.offset(offset);
}
return query;
}
}import type { InferSelectModel, SQL } from 'drizzle-orm';
import type { AnyPgTable } from 'drizzle-orm/pg-core';
import type { DB, DBTransaction } from './client';
export interface RepositoryOptions {
db?: DB;
tx?: DBTransaction;
}
/**
* A generic base repository class for Drizzle ORM
*
* Note: This implementation uses type assertions in some places to work
* around limitations in TypeScript's ability to fully type the Drizzle ORM.
* The public API is fully typed, but internal implementations may use 'any'.
*/
export class BaseRepository<
TTable extends AnyPgTable,
TSelect = InferSelectModel<TTable>,
> {
protected table: TTable;
protected db: DB | DBTransaction;
constructor(table: TTable, db: DB | DBTransaction) {
this.table = table;
this.db = db;
}
/**
* Find all records matching the given criteria
*/
async findAll(
options: {
limit?: number;
offset?: number;
orderBy?: SQL<unknown>;
where?: SQL<unknown>;
} = {},
): Promise<TSelect[]> {
const { limit, offset, orderBy, where } = options;
// Using any to avoid complex type issues with the query builder
let query = this.db.select().from(this.table).$dynamic();
if (where) {
query = query.where(where);
}
if (orderBy) {
query = query.orderBy(orderBy);
}
if (limit) {
query = query.limit(limit);
}
if (offset) {
query = query.offset(offset);
}
return query;
}
}