Common Fields Logic For Multiple Tables

I have a set of tables inheriting the same set of columns:

export const base = {
  id: text()
    .primaryKey()
    .$defaultFn(() => Crypto.randomUUID()),
  local_created_at: integer({ mode: "timestamp_ms" })
    .notNull()
    .$defaultFn(() => new Date()),
  local_updated_at: integer({ mode: "timestamp_ms" })
    .notNull()
    .$defaultFn(() => new Date())
    .$onUpdateFn(() => new Date()),
  is_deleted: integer({ mode: "boolean" }).notNull().default(false),
  synched: integer({ mode: "boolean" }).notNull(),
}

export const table1 = {
  ...base,
  some_custom_fields...
}

export const table2 = {
  ...base,
  some_custom_fields...
}


I want to define a base class with common functionality for these two tables. It should look something like that:

export class BaseRepository<
  Schema extends SQLiteTable<TableConfig> & {
    id: AnySQLiteColumn & IndexColumn;
    local_created_at: AnySQLiteColumn;
    local_updated_at: AnySQLiteColumn;
    is_deleted: AnySQLiteColumn;
    synched: AnySQLiteColumn;
  }, {
  protected schema: Schema;

  constructor(schema: Schema) {
    this.schema = schema;
  }

  async save(payload: InferInsertModel<Schema>) {
    const results = await db
      .insert(this.schema)
      .values(payload)
      .onConflictDoUpdate({
        target: this.schema.id,
        set: payload,
      })
      .returning();

    return results?.[0];
  }

  async getAllNotSynced() {
    return await db
      .select()
      .from(this.schema)
      .where(eq(this.schema.synched, false));
  }

  other_cool_helper_functions...
}


How do I do so properly to avoid maximum of the TypeScript pain? So far can't figure out a clean solution.
Was this page helpful?