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

如何配置TypeScript/ESLint在knex返回any类型时强制报错?

可落地的强制类型校验方案

以下方案组合使用可以完全杜绝knex查询隐式返回any的问题,不需要额外引入重型工具:

  • 首先开启TypeScript+ESLint的全严格校验规则,从编译、lint层阻断隐式any流转
    在tsconfig.json中开启核心严格配置:

    {
      "compilerOptions": {
        "strict": true,
        "noImplicitAny": true,
        "strictNullChecks": true
      }
    }
    

    配合ESLint的TypeScript规则集开启三个核心校验:@typescript-eslint/no-unsafe-assignment、@typescript-eslint/no-unsafe-call、@typescript-eslint/no-unsafe-member-access。配置完成后,只要knex查询返回了any类型,后续对返回值的赋值、方法调用、属性读取操作都会直接报错,根本无法通过本地校验和流水线卡点。

  • 初始化knex时全局注册表结构类型映射,从根源避免漏标类型
    不要每次查询单独传入泛型,通过knex内置的类型扩展接口,把项目里所有数据表的结构统一注册,之后所有常规查询都会自动推导返回类型,未注册的表名会直接抛类型错误,不会回退到any:

    import { Knex, knex } from 'knex';
    
    // 提前定义各表的字段类型
    interface User {
      id: number;
      username: string;
      createTime: Date;
    }
    interface Order {
      id: number;
      userId: number;
      payAmount: number;
    }
    
    // 扩展knex内置的Tables类型,绑定表名和对应结构
    declare module 'knex/types/tables' {
      interface Tables {
        users: Knex.CompositeTableType<
          User,
          // 插入操作的字段类型:id自增、createTime可自动生成,只要求必传username
          Pick<User, 'username'> & Partial<Pick<User, 'createTime'>>,
          // 更新操作的字段类型:不允许修改id,其余字段可选
          Partial<Omit<User, 'id'>>
        >;
        orders: Order;
      }
    }
    
    // 初始化的实例所有查询自动匹配类型,不需要手动传泛型
    const db = knex({ /* 数据库连接配置 */ });
    // 这里返回值自动推导为User[],不会出现any
    const userList = await db('users').select('*');
    

    如果写了未在Tables中注册的表名,TS会直接抛出类型错误,从入口就避免漏配表结构的问题。

  • 封装通用查询方法,强制要求传入明确类型
    如果项目里存在大量复杂联表查询、内置类型推导覆盖不到的场景,可以封一层通用查询函数,把返回类型设为必须传入的泛型参数,不传的话返回值会被推导为never,使用时直接报错:

    async function strictQuery<TResult = never>(
      buildQuery: (db: Knex) => Knex.QueryBuilder
    ): Promise<TResult[]> {
      const result = await buildQuery(db);
      return result as TResult[];
    }
    
    // 漏传泛型的话返回值是never,根本无法正常使用
    // 正确写法必须明确标注返回类型
    const orderList = await strictQuery<{id: number; username: string; payAmount: number}>(
      (k) => k('users').leftJoin('orders', 'users.id', 'orders.userId').select('*')
    );
    

注意:不要为了过校验随便给查询结果标any,只要上述配置全开,出现any就意味着要么表结构没注册、要么查询逻辑存在类型漏洞,顺着报错补齐类型定义即可,完全可以做到全链路无隐式any。

内容的提问来源于stack exchange,提问作者JonathanR

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 08:42:28