Pagination proper TypeScript return types generics
Hi, I am having some hard time during implementation of basic pagination function. I wanted to make it as generic as possible but not able to get to the point where I will be able to access specific property from a specific model. Below is some basic code snippet which I am trying to implement
export type PaginationResult<T> = {
data: T
page: number
pageSize: number
}
export class MyRepository extends BaseRepository<typeof users> {
constructor() {
super(users)
}
async findAll() {
const users = await super.findAll()
users.data[0] // no proper suggestion here
return users
}
}
@Injectable()
export class BaseRepository<T extends PgTable> {
constructor(protected readonly schema: T) {}
async findAll() {
const query = db.select().from(this.schema).where(eq(this.schema.id, 1))
const dynamicQuery = query.$dynamic()
return await this.withPagination(dynamicQuery, 1)
}
async withPagination<T extends PgSelect>(
qb: T,
orderByColumn: PgColumn | SQL | SQL.Aliased,
page = 1,
pageSize = 3,
) {
const data = await qb
.orderBy(orderByColumn)
.limit(pageSize)
.offset((page - 1) * pageSize)
return {
data,
page,
pageSize,
totalCount: 1000,
}
}
}
export type PaginationResult<T> = {
data: T
page: number
pageSize: number
}
export class MyRepository extends BaseRepository<typeof users> {
constructor() {
super(users)
}
async findAll() {
const users = await super.findAll()
users.data[0] // no proper suggestion here
return users
}
}
@Injectable()
export class BaseRepository<T extends PgTable> {
constructor(protected readonly schema: T) {}
async findAll() {
const query = db.select().from(this.schema).where(eq(this.schema.id, 1))
const dynamicQuery = query.$dynamic()
return await this.withPagination(dynamicQuery, 1)
}
async withPagination<T extends PgSelect>(
qb: T,
orderByColumn: PgColumn | SQL | SQL.Aliased,
page = 1,
pageSize = 3,
) {
const data = await qb
.orderBy(orderByColumn)
.limit(pageSize)
.offset((page - 1) * pageSize)
return {
data,
page,
pageSize,
totalCount: 1000,
}
}
}
2 Replies
I see that you wrote
super.findAll()
don't you mean this.findAll()
?Otherwise it will be recursive calls to itself.
This one works but I would like to be able to specify explicit return types to have controll over it
export class MyRepository extends BaseRepository<typeof users> {
constructor(@Inject(PG_CONNECTION) private db: NodePgDatabase<typeof schema>) {
super(users, db)
}
async findAll() {
const query = super.findAll()
const result = await query
return result
}
}
@Injectable()
export class BaseRepository<T extends PgTable> {
constructor(
protected readonly schema: T,
protected readonly db: NodePgDatabase,
) {}
findAll() {
const query = this.db.select().from(this.schema).where(eq(this.schema.id, 1))
const dynamicQuery = query.$dynamic()
return this.withPagination(dynamicQuery)
// return await this.withPagination(dynamicQuery, 1)
}
async withPagination<M extends PgSelect>(qb: M, orderByColumn: PgColumn | SQL | SQL.Aliased, page = 1, pageSize = 3) {
const data = await qb
.orderBy(orderByColumn)
.limit(pageSize)
.offset((page - 1) * pageSize)
return {
data,
page,
pageSize,
totalCount: 1000,
}
}
}
export class MyRepository extends BaseRepository<typeof users> {
constructor(@Inject(PG_CONNECTION) private db: NodePgDatabase<typeof schema>) {
super(users, db)
}
async findAll() {
const query = super.findAll()
const result = await query
return result
}
}
@Injectable()
export class BaseRepository<T extends PgTable> {
constructor(
protected readonly schema: T,
protected readonly db: NodePgDatabase,
) {}
findAll() {
const query = this.db.select().from(this.schema).where(eq(this.schema.id, 1))
const dynamicQuery = query.$dynamic()
return this.withPagination(dynamicQuery)
// return await this.withPagination(dynamicQuery, 1)
}
async withPagination<M extends PgSelect>(qb: M, orderByColumn: PgColumn | SQL | SQL.Aliased, page = 1, pageSize = 3) {
const data = await qb
.orderBy(orderByColumn)
.limit(pageSize)
.offset((page - 1) * pageSize)
return {
data,
page,
pageSize,
totalCount: 1000,
}
}
}