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

Express+TypeScript+Objection 泛型传Model给父类失效问题

问题根源

类型定义错位导致两个连锁问题:

  1. 初始代码里BaseService的构造函数参数、m属性都标注为泛型Models对应的实例类型,当你直接传入UserModel类本身时,TS检测到类型不匹配,才会提示需要加new关键字生成实例
  2. 按提示传入new UserModel()实例后,类型报错消失,但Objection.js的query()、findById()等查询方法都是静态方法,挂载在模型类上,模型实例上不存在这些方法,自然无法正常执行查询。
正确实现代码

Objection.js官方自带ModelClass工具类型,专门用来标记模型类本身(而非实例)的类型,直接用就能解决类型匹配问题:

import { Model, ModelClass } from 'objection';

class BaseService<M extends Model> {
  public model: ModelClass<M>;

  constructor(model: ModelClass<M>) {
    this.model = model;
  }

  // 可直接在基类封装通用CRUD方法,所有子类自动复用
  async getById(id: number | string) {
    return this.model.query().findById(id);
  }
}

class MyService extends BaseService<UserModel> {
  constructor() {
    // 直接传入模型类即可,无类型报错
    super(UserModel);
  }

  async queryUser() {
    // 两种调用方式都能正常运行,带完整类型提示
    const user1 = await this.model.query().findById(1);
    const user2 = await this.getById(1);
    return user1;
  }
}
注意事项
  • 禁止传入模型实例:所有knex/Objection的查询入口都是模型类的静态方法,实例不携带这些静态方法,传入实例必然导致查询逻辑失效
  • 泛型约束M extends Model会自动校验传入的模型是否符合Objection的Model规范,同时给查询结果提供完整的类型推导
  • 不需要自己手写构造函数类型,直接用官方提供的ModelClass即可,避免手动写类型遗漏静态方法的定义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 22:57:27