You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Drizzle pg的SelectedFields转换为普通类型?

解决Drizzle仓库模式中SelectedFields返回类型不匹配问题

核心问题是Drizzle的SelectedFields类型属于内部列类型集合,无法直接映射到查询返回的普通对象类型,需要借助Drizzle内置的类型工具推导正确的返回类型。

解决方案步骤

  • 引入Drizzle内置的类型工具,专门处理查询结果的类型转换
  • 修改BaseRepository中findFirstBy方法的泛型定义,分别处理传参和不传参的类型推导逻辑

完整代码示例

修改后的BaseRepository实现

import { PgTable, SelectedFields, Where, SelectedFieldsFlat, GetSelectResult } from 'drizzle-orm/pg-core';
import { db } from './your-db-connection'; // 替换为你的数据库连接实例

class BaseRepository<T extends PgTable> {
  constructor(public table: T) {}

  async findFirstBy<Select extends SelectedFields<T> | undefined = undefined>(
    where: Where<T>,
    select?: Select
  ): Promise<
    Select extends undefined 
      ? T['$inferSelect'] // 使用表内置的查询结果推断类型
      : GetSelectResult<T, SelectedFieldsFlat<Select>>
  > {
    const query = db.select(select || this.table).from(this.table).where(where).limit(1);
    return await query;
  }
}

调用示例

// 示例表定义
import { pgTable, serial, varchar, eq } from 'drizzle-orm/pg-core';

const users = pgTable('users', {
  id: serial('id').primaryKey(),
  name: varchar('name', { length: 255 }),
  email: varchar('email', { length: 255 }).unique(),
});

// 初始化仓库实例
const userRepo = new BaseRepository(users);

// 场景1:不传select参数,返回完整表结构类型
const fullUser = await userRepo.findFirstBy(eq(users.id, 1));
// fullUser类型:{ id: number; name: string; email: string }

// 场景2:传select参数,返回选中字段的扁平普通类型
const partialUser = await userRepo.findFirstBy(
  eq(users.id, 1),
  { name: users.name, email: users.email }
);
// partialUser类型:{ name: string; email: string }

关键类型说明

  • SelectedFieldsFlat<Select>:将传入的SelectedFields转换为扁平的列集合类型,自动处理嵌套或别名列的结构
  • GetSelectResult<T, SelectedFieldsFlat<Select>>:基于表结构和扁平列集合,推导出与实际查询结果完全匹配的普通对象类型
  • T['$inferSelect']:Drizzle表类型内置的推断属性,用于获取完整表查询的返回类型,比直接使用T更准确

内容的提问来源于stack exchange,提问作者CodeRevenge

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 21:05:04