Correct Client type to pass drizzle client around

Hey community, I love drizzle but sometimes I find it quite challenging to deal with the types. I am not sure if this problem is a skill issue, thus I wanna ask you guys. Let me explain: I am using Nest.js and I have DatabaseService file that create the drizzle client internally and exposes it. I want this service to be dynamic which means I want to be able to pass the schema to it and the type of the client should be infered automagically. But I am struggling to properly type it: This is the relevant definitions of my types in the DatabaseService regarding the drizzle client:
type DB<TSchema extends Record<string, unknown>> = PgDatabase<NodePgQueryResultHKT, TSchema> & {
$client: NodePgClient;
};
export declare class DatabaseService<T extends Record<string, unknown>> {
private readonly _client;
client: DB<T>;
get db(): DB<T>;
}
type DB<TSchema extends Record<string, unknown>> = PgDatabase<NodePgQueryResultHKT, TSchema> & {
$client: NodePgClient;
};
export declare class DatabaseService<T extends Record<string, unknown>> {
private readonly _client;
client: DB<T>;
get db(): DB<T>;
}
The underlying schema that I am importing is:
export const offerSkills = pgTable("offer_skills", {
id: uuid().defaultRandom().primaryKey().notNull(),
offerId: uuid().notNull(),
skillId: uuid().notNull(),
mandatory: boolean("mandatory"),
createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(),
updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(),
})
export const offerSkills = pgTable("offer_skills", {
id: uuid().defaultRandom().primaryKey().notNull(),
offerId: uuid().notNull(),
skillId: uuid().notNull(),
mandatory: boolean("mandatory"),
createdAt: timestamp("created_at", { mode: 'string' }).defaultNow().notNull(),
updatedAt: timestamp("updated_at", { mode: 'string' }).defaultNow().notNull(),
})
1 Reply
François
FrançoisOP3w ago
I am using the client like this: I am using this class in another service like this:
import * as schema from "drizzle/schema"

constructor(private database: DatabaseService<typeof schema>) {}

public addSkillToOffer(skillId: string, offerId: string, m: boolean, opts?: {tx: any}) {
return Try.success(skillId)
.flatMap(skillId => this.existsById(skillId))
.filter(exists => !exists, () => {throw new SkillNotFoundException(skillId)})

.map(() => this.database.client.insert(offerSkills).values({
offerId: offerId,
skillId: skillId,
mandatory: m
}).returning())
}
import * as schema from "drizzle/schema"

constructor(private database: DatabaseService<typeof schema>) {}

public addSkillToOffer(skillId: string, offerId: string, m: boolean, opts?: {tx: any}) {
return Try.success(skillId)
.flatMap(skillId => this.existsById(skillId))
.filter(exists => !exists, () => {throw new SkillNotFoundException(skillId)})

.map(() => this.database.client.insert(offerSkills).values({
offerId: offerId,
skillId: skillId,
mandatory: m
}).returning())
}
The insert call gives me the following type error:
No overload matches this call.
Overload 1 of 2, '(value: { skillId: string | SQL<unknown> | Placeholder<string, any>; offerId: string | SQL<unknown> | Placeholder<string, any>; }): PgInsertBase<PgTableWithColumns<{ name: "offer_skills"; schema: undefined; columns: { ...; }; dialect: "pg"; }>, ... 4 more ..., never>', gave the following error.
Object literal may only specify known properties, and 'mandatory' does not exist in type '{ skillId: string | SQL<unknown> | Placeholder<string, any>; offerId: string | SQL<unknown> | Placeholder<string, any>; }'.
Overload 2 of 2, '(values: { skillId: string | SQL<unknown> | Placeholder<string, any>; offerId: string | SQL<unknown> | Placeholder<string, any>; }[]): PgInsertBase<PgTableWithColumns<{ name: "offer_skills"; schema: undefined; columns: { ...; }; dialect: "pg"; }>, ... 4 more ..., never>', gave the following error.
Object literal may only specify known properties, and 'offerId' does not exist in type '{ skillId: string | SQL<unknown> | Placeholder<string, any>; offerId: string | SQL<unknown> | Placeholder<string, any>; }[]'.
No overload matches this call.
Overload 1 of 2, '(value: { skillId: string | SQL<unknown> | Placeholder<string, any>; offerId: string | SQL<unknown> | Placeholder<string, any>; }): PgInsertBase<PgTableWithColumns<{ name: "offer_skills"; schema: undefined; columns: { ...; }; dialect: "pg"; }>, ... 4 more ..., never>', gave the following error.
Object literal may only specify known properties, and 'mandatory' does not exist in type '{ skillId: string | SQL<unknown> | Placeholder<string, any>; offerId: string | SQL<unknown> | Placeholder<string, any>; }'.
Overload 2 of 2, '(values: { skillId: string | SQL<unknown> | Placeholder<string, any>; offerId: string | SQL<unknown> | Placeholder<string, any>; }[]): PgInsertBase<PgTableWithColumns<{ name: "offer_skills"; schema: undefined; columns: { ...; }; dialect: "pg"; }>, ... 4 more ..., never>', gave the following error.
Object literal may only specify known properties, and 'offerId' does not exist in type '{ skillId: string | SQL<unknown> | Placeholder<string, any>; offerId: string | SQL<unknown> | Placeholder<string, any>; }[]'.
Both errors are unexplainable to me and after a long time of tinkering around I am out of ideas. I have no idea what the proper type of the drizzle client is so that I can pass it to other functions
const valuesToInsert: InferInsertModel<typeof offerSkills> = {
offerId: offerId,
skillId: skillId,
mandatory: m
};
return this.database.client.insert<typeof offerSkills>(offerSkills).values(valuesToInsert).returning()
const valuesToInsert: InferInsertModel<typeof offerSkills> = {
offerId: offerId,
skillId: skillId,
mandatory: m
};
return this.database.client.insert<typeof offerSkills>(offerSkills).values(valuesToInsert).returning()
This will also give the error:
Object literal may only specify known properties, and 'mandatory' does not exist in type '{ skillId: string; offerId: string; }'.
Object literal may only specify known properties, and 'mandatory' does not exist in type '{ skillId: string; offerId: string; }'.
But the table definition, as seen above includes this column

Did you find this page helpful?