使用 knex.js 和 TypeScript 根据条件构造查询

Construct query based on conditions using knex.js and TypeScript

我想构造一个查询,根据是否传递了 name and/or city,它应该添加一个 where 子句。

我没有在文档中找到执行此操作的具体方法,因此我尝试在查询中附加 where 方法,但可能未能指定类型。

let query: Knex.QueryBuilder = await knex<Member>('members')

if (name) {
  query = query.where('name', String(name))
}

if (city) {
  query = query.where('city', String(city))
}

const members: Member[] = query.select('*')

TypeError: query.select is not a function

此外,TypeScript 警告:

让查询

Type 'Member[]' is missing the following properties from type 'QueryBuilder<any, any>': client, or, not, and, and 118 more.

常量成员

Type 'QueryBuilder<any, DeferredKeySelection<any, string, false, {}, false, {}, never> | DeferredKeySelection<any, string, false, {}, false, {}, never>[]>' is missing the following properties from type 'Member[]': length, pop, push, concat, and 25 more.

Knex.js 有一个伪造的 then 实现,调用时将在数据库上执行查询。

因此您只需要将 await(然后调用)移动到最后一部分。

它应该是这样的:

let query: Knex.QueryBuilder = knex<Member>('members');
// ---------------------------^

if (name) {
  query = query.where('name', String(name));
}

if (city) {
  query = query.where('city', String(city));
}

const members: Member[] = await query.select('*');

更好看的构造将使用 modify

const members: Member[] = await knex<Member>('members')
  .select('*')
  .modify((queryBuilder) => {
    if (name) {
      queryBuilder.where('name', String(name));
    }

    if (city) {
      queryBuilder.where('city', String(city));
    }

    return queryBuilder;
  });