扩展Knex返回非QueryBuilder实例时触发TypeScript错误
解决Knex扩展QueryBuilder返回非QueryBuilder类型的TypeScript错误
问题场景
尝试给Knex的QueryBuilder添加toPrismaSql方法,将Knex查询转换为Prisma.Sql对象(类似.toSQL()的非链式返回逻辑),但触发TypeScript类型错误,提示返回的Sql类型无法匹配QueryBuilder或Promise相关类型要求。
原代码
import Knex from 'knex' import { Prisma } from '@prisma/client' Knex.QueryBuilder.extend('toPrismaSql', function() { const { bindings, sql } = this.toSQL() if (sql.includes('??')) { throw new Error(`Cannot convert identifiers ??. SQL query: ${sql}`) } return Prisma.sql(sql.split('?'), ...bindings) }) export const knex = Knex({ client: 'postgres' })
TypeScript错误信息
Argument of type < TRecord extends {} = any, TResult extends {} = unknown[] >( this: QueryBuilder<TRecord, TResult> ) => Sql is not assignable to parameter of type < TRecord extends {} = any, TResult extends {} = unknown[] >( this: QueryBuilder<TRecord, TResult>, ...args: any[] ) => QueryBuilder<TRecord, TResult> | Promise<Resolve<TResult> | QueryBuilder<TRecord | TResult, any>> Type 'Sql' is not assignable to type 'QueryBuilder<TRecord, TResult> | Promise<Resolve<TResult> | QueryBuilder<TRecord | TResult, any>> ts(2345)
解决方案
1. 添加Knex类型扩展声明
创建knex.d.ts类型声明文件,扩展QueryBuilder接口,定义自定义方法的返回类型:
import Knex from 'knex' import { Prisma } from '@prisma/client' declare module 'knex' { interface QueryBuilder<TRecord extends {} = any, TResult extends {} = unknown[]> { toPrismaSql(): Prisma.Sql } }
2. 调整原代码引入类型声明
修改原代码,确保类型声明被TypeScript识别(若项目中未自动加载,需调整tsconfig.json的include配置,加入该声明文件路径):
import Knex from 'knex' import { Prisma } from '@prisma/client' import './knex.d.ts' Knex.QueryBuilder.extend('toPrismaSql', function() { const { bindings, sql } = this.toSQL() if (sql.includes('??')) { throw new Error(`Cannot convert identifiers ??. SQL query: ${sql}`) } return Prisma.sql(sql.split('?'), ...bindings) }) export const knex = Knex({ client: 'postgres' })
原理说明
Knex的默认TypeScript定义约束了扩展方法必须返回QueryBuilder实例或Promise,但我们的方法需要返回Prisma.Sql。通过扩展Knex的模块类型声明,手动告知TypeScripttoPrismaSql方法的正确返回类型,即可解决类型不兼容问题。
内容的提问来源于stack exchange,提问作者Pierre Noël
相关产品推荐
相关产品推荐

