如何实现表示含指定列的Drizzle表的TypeScript约束类型?
问题:创建包含特定列集合的Drizzle表类型约束
我希望创建一个TypeScript类型,用于表示所有包含特定列集合的Drizzle表,目的是将该类型作为泛型的类型约束。示例代码如下:
const columns = { createdBy: text('created_by').references(() => user.id), updatedBy: text('updated_by').references(() => user.id), } type TableWithUserColumns = Xxx<typeof columns> async function selectWithUserJoined<T extends TableWithUserColumns>(tbl: T): Promise<SelectWithUserJoined<T>> { // 逻辑:从tbl查询并关联user表 }请问该如何实现上述代码中的
Xxx类型?我曾尝试使用PgTableWithColumns但未能正确运用。
解决方案
要实现目标类型,核心是基于Drizzle的PgTable类型,结合TypeScript的类型约束,强制要求表必须包含指定的列集合,同时保留原表的完整类型信息。
1. 提取必填列的类型结构
先定义你需要强制要求的列,然后提取它们的类型:
import type { PgTable } from 'drizzle-orm/pg-core'; import { text } from 'drizzle-orm/pg-core'; // 假设user是已定义的用户表 const user = /* 你的用户表定义 */; const requiredUserColumns = { createdBy: text('created_by').references(() => user.id), updatedBy: text('updated_by').references(() => user.id), }; // 提取必填列的类型结构 type RequiredUserColumnStructure = typeof requiredUserColumns;
2. 实现约束类型(替换原代码中的Xxx)
定义一个泛型类型,约束传入的表必须是PgTable的子类,且其columns属性包含所有必填列:
type TableWithRequiredColumns<TColumns extends Record<string, any>> = PgTable & { columns: PgTable['columns'] & TColumns; }; // 替换原代码中的Xxx,得到你需要的类型 type TableWithUserColumns = TableWithRequiredColumns<RequiredUserColumnStructure>;
3. 验证泛型函数的约束
现在你的selectWithUserJoined函数可以正确限制传入的表必须包含createdBy和updatedBy列,同时在函数内部可以安全地访问这些列:
// 定义关联后的返回类型(示例) type SelectWithUserJoined<T extends TableWithUserColumns> = { // 保留原表的所有字段 ...T['$inferSelect'], // 新增关联的用户信息 creator: typeof user['$inferSelect'], updater: typeof user['$inferSelect'] }; async function selectWithUserJoined<T extends TableWithUserColumns>(tbl: T): Promise<SelectWithUserJoined<T>> { // 这里可以安全地使用tbl.createdBy和tbl.updatedBy进行关联 const result = await db.select({ ...tbl, creator: user, updater: user }) .from(tbl) .leftJoin(user, eq(tbl.createdBy, user.id)) .leftJoin(user, eq(tbl.updatedBy, user.id)); return result[0]; }
关于PgTableWithColumns的说明
PgTableWithColumns是Drizzle用于构建新表类型的工具类型,它的作用是根据传入的列定义生成完整的表类型,而非对已有表类型进行约束。我们上面的实现是在已有PgTable基础上追加列约束,更贴合你的需求场景。
内容的提问来源于stack exchange,提问作者totooooo
相关产品推荐
相关产品推荐

