How can I extend drizzle tables?

I noticed that I write a lot of boilerplate code. When I had to update one of such types, I refactored them a bit, into reusable thing:
// /__prefabs.ts
import { sql } from "drizzle-orm"
import { datetime, varchar, int } from "drizzle-orm/mysql-core"
import { User } from "./NextAuth"

export const id = int("id").primaryKey().autoincrement()
export const name = varchar("name", { length: 191 }).notNull()
export const slug = varchar("slug", { length: 191 }).notNull()

export const Updated = {
  updatedAt: datetime("updatedAt", { mode: "date", fsp: 3 })
    .default(sql`CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3)`)
    .notNull(),
  updatedById: varchar("updatedById", { length: 191 }).references(
    () => User.id,
    { onDelete: "set null", onUpdate: "cascade" }
  )
}

// Category.ts
import { mysqlTable, unique } from "drizzle-orm/mysql-core"
import { id, name, slug, Updated } from "./__prefabs"

export const Category = mysqlTable(
  "Category",
  {
    id,
    name,
    slug,
    ...Updated
  },
  (table) => {
    return {
      Category_name_key: unique("Category_name_key").on(table.name),
      Category_slug_key: unique("Category_slug_key").on(table.slug)
    }
  }
)


This worked out pretty well for that time. But now, I keep writing tons of services, and I want to make some reusable functions, but I struggle with TS trying to do that. i.e. I want to make a service getItems:
// services/getItems.ts
import { db } from "@/app/(db)"
import { type Table } from "drizzle-orm"

type ItemTable = {
  id: number,
  name: string,
  slug: string
}

export async function getItems<T extends ItemTable>(table: Table<T>) {
  return db
    .select({
      id: table.id,
      name: table.name,
      slug: table.slug
    })
    .from(table)
}

But types on this thing are totally wrong, and I'm not sure where should I start to approach this problem.

Another example, I have some subqueries like these:
const getProblemId = db
  .select({
    id: Problem.id
  })
  .from(Problem)
  .where(eq(Problem.slug, sql.placeholder("problemSlug")))
  .limit(1)

It would be nice if I could refactor it into getID, that takes Table as prop:
const getID = (Table) => db
  .select({
    id: Table.id
  })
  .from(Table)
  .where(eq(Table.slug, sql.placeholder("slug")))
  .limit(1)

But I just don't get how to define the Table type in TS.
Was this page helpful?