Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Typescript] Can't return something else than knex in the extend function #6091

Open
petersg83 opened this issue Jun 28, 2024 · 1 comment
Open

Comments

@petersg83
Copy link

petersg83 commented Jun 28, 2024

Environment

Knex version: 3.1.0

Bug

Problem

I'm trying to extend knex with a function that would return something that is not the queryBuilder instance. I guess the same way that .toSQL() returns an object that is not the queryBuilder.

However I'm having a typescript error. I'm not a typescript expert and I wonder if I can solve this problem or if a typescript change is needed in the knex library. I was expecting to be able to return anything.

My code:

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' })

The typescript error:

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)

Reproduce error

You can test the code there: https://replit.com/@replit77i18/Knex-extend-typescript-error#index.ts

@KristjanTammekivi
Copy link
Contributor

Can replicate, no nicer solution than adding an as any after the return. Good news is that it's not the worst as any in history, it wouldn't infer the return type anyway. For that you can just augment knex type

declare module 'knex' {
    namespace Knex {
        interface QueryBuilder<TRecord extends {} = any, TResult = any> {
            toPrismaSql(): ReturnType<typeof Prisma.sql>
        }
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants