Drizzle ORM:封装查询API调用时如何维持类型定义?
解决Drizzle查询封装函数的类型丢失问题
问题根源
你之前的泛型方案仅约束了参数类型,但未明确关联返回类型与传入的opts参数,导致TypeScript无法根据columns/with等配置推导正确的返回值类型。
正确实现方案
1. 提取Drizzle查询的类型定义
先把myThings.findFirst的参数和返回类型提取出来,方便后续复用:
// 提取findFirst的参数类型 type MyThingFindFirstOpts = Parameters<typeof db.query.myThings.findFirst>[0]; // 定义基于参数类型的返回类型 type MyThingFindFirstResult<T extends MyThingFindFirstOpts> = ReturnType<typeof db.query.myThings.findFirst<T>>;
2. 重构封装函数
显式指定返回类型为MyThingFindFirstResult<T>,同时合并授权条件与传入的where(避免覆盖用户传入的额外查询条件):
async function loadMyThing<T extends MyThingFindFirstOpts>( user: User, id: ThingId, opts?: T ): Promise<MyThingFindFirstResult<T>> { return db.query.myThings.findFirst({ ...opts, where: (t, { and, eq }) => and( // 强制添加授权校验条件 eq(t.owner, user.id), eq(t.id, id), // 合并用户传入的where条件(如果存在) opts?.where ? opts.where(t, { and, eq }) : undefined ), }) as Promise<MyThingFindFirstResult<T>>; }
3. 验证类型正确性
现在传入with或columns选项时,返回值类型会自动匹配配置:
const thing = await loadMyThing(me, thingId, { with: { thingRelation: true } }); // ✅ 类型推导正确,thingRelation可正常访问 thing!.thingRelation;
关键说明
- 显式关联泛型参数
T与返回类型,让TypeScript能根据opts的配置精准推导结果类型 - 合并
where条件而非直接覆盖,既保留授权校验逻辑,又支持用户传入额外查询约束 - 类型断言
as Promise<MyThingFindFirstResult<T>>用于消除TypeScript的类型歧义,确保推导准确
内容的提问来源于stack exchange,提问作者Daniel Baulig
相关产品推荐
相关产品推荐

