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

TypeScript大型泛型变量类型设置及Drizzle相关技术问题

Drizzle ORM RelationalQueryBuilder 类型问题解答

1. 自定义函数复用findMany的Config类型

无需复制粘贴类型,直接从RelationalQueryBuilder的findMany方法上提取对应类型即可,推荐用TypeScript内置的Parameters工具类型:

import { RelationalQueryBuilder, TablesRelationalConfig, TableRelationalConfig } from 'drizzle-orm/pg-core';

// 提取findMany的config参数类型
type FindManyConfig<TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig> = 
  Parameters<RelationalQueryBuilder<TSchema, TFields>['findMany']>[0];

自定义函数示例:

function customFindMany<TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig>(
  builder: RelationalQueryBuilder<TSchema, TFields>,
  config?: FindManyConfig<TSchema, TFields>
) {
  // 直接复用findMany的config类型约束
  return builder.findMany(config);
}

如果需要更精准的类型(对应findMany泛型的约束),也可以直接引用原类型:

type FindManyConfig<TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig> = 
  KnownKeysOnly<DBQueryConfig<'many', true, TSchema, TFields>, DBQueryConfig<'many', true, TSchema, TFields>>;

不过前者更灵活,不需要依赖Drizzle内部的DBQueryConfig和KnownKeysOnly类型。

2. findMany自动推导泛型的原理

当调用findMany时,TypeScript通过泛型反向推导自动确定类型:

  • 首先,db.query.example是针对example表实例化的RelationalQueryBuilder,其TSchema和TFields泛型已经固定为该表的结构类型
  • 你传入的config参数(比如{ where: ... })会被TypeScript匹配到findMany的泛型约束DBQueryConfig<'many', true, TSchema, TFields>
  • TypeScript会自动推导TConfig为你传入的config的具体类型,同时确保它符合约束,最终生成对应的返回值类型

简单来说,实例化后的RelationalQueryBuilder已经绑定了表结构类型,TypeScript只需要根据你传入的config参数,自动补全TConfig泛型,无需显式声明。

3. 存储Config的自定义类示例

以下是带正确类型约束的自定义类,用于存储findMany的config:

import { RelationalQueryBuilder, TablesRelationalConfig, TableRelationalConfig } from 'drizzle-orm/pg-core';

// 提取findMany的config类型
type FindManyConfig<TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig> = 
  Parameters<RelationalQueryBuilder<TSchema, TFields>['findMany']>[0];

class QueryConfigStore<TSchema extends TablesRelationalConfig, TFields extends TableRelationalConfig> {
  private storedConfig: FindManyConfig<TSchema, TFields> | undefined;

  constructor(private builder: RelationalQueryBuilder<TSchema, TFields>) {}

  // 存储符合类型约束的config
  saveConfig(config: FindManyConfig<TSchema, TFields>) {
    this.storedConfig = config;
  }

  // 使用存储的config执行查询
  async executeStoredQuery() {
    return this.builder.findMany(this.storedConfig);
  }
}

// 使用示例
const exampleStore = new QueryConfigStore(db.query.example);
exampleStore.saveConfig({
  where: (posts, { eq }) => eq(posts.id, 1),
});
const result = await exampleStore.executeStoredQuery();

这个类通过泛型与具体的RelationalQueryBuilder实例绑定,确保存储的config完全匹配该实例findMany方法的类型要求,不会出现类型不兼容的问题。

内容的提问来源于stack exchange,提问作者ali.turan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:32:45