Common Fields Logic For Multiple Tables
I have a set of tables inheriting the same set of columns:
I want to define a base class with common functionality for these two tables. It should look something like that:
How do I do so properly to avoid maximum of the TypeScript pain? So far can't figure out a clean solution.
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...
}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...
}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.