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
相关产品推荐
相关产品推荐

