Express+Knex+Objection中BaseService通用方法编写问题求解
问题原因
- 泛型无约束:
BaseService的泛型Models没有绑定Objection模型类型,TS无法识别传入参数上的query()方法,类型校验和运行时都会出问题 - 语法错误:
find()方法未声明async,直接在方法内使用await会触发语法错误 - API调用错误:代码里的
findAll()是Sequelize的ORM方法,Objection原生不存在该API,直接调用会报方法不存在的错误 - 拼写错误:多处将
UserModel拼为UserMoodel,会直接导致引用失败 - 模型配置缺失:Objection模型必须声明静态
tableName属性,否则无法正常执行查询
可落地的封装方案
1. 修正基类BaseService
添加Objection内置的ModelClass泛型约束,补全正确的通用方法逻辑:
// base.service.ts import { Model, ModelClass } from 'objection'; class BaseService<M extends Model> { // 存储传入的模型类 protected model: ModelClass<M>; constructor(model: ModelClass<M>) { this.model = model; } // 通用查询全量方法 public async find(): Promise<M[]> { // Objection直接调用query()默认构造select * from 表名的查询,等价于全量查询 return this.model.query(); } // 可按需扩展其他通用CRUD方法 public async findById(id: number | string): Promise<M | undefined> { return this.model.query().findById(id); } public async create(data: Partial<M>): Promise<M> { return this.model.query().insert(data); } public async updateById(id: number | string, data: Partial<M>): Promise<number> { return this.model.query().patchAndFetchById(id, data).then(res => res ? 1 : 0); } public async deleteById(id: number | string): Promise<number> { return this.model.query().deleteById(id); } } export default BaseService;
2. 修正User模型
修正拼写,补全Objection要求的必填配置:
// user.model.ts import { Model } from 'objection'; export class UserModel extends Model { // 必填:绑定对应的数据表名 static tableName = 'users'; // 按需定义字段、关联关系、校验规则 id!: number; username!: string; email!: string; }
3. 修正UserService
继承时传入正确的模型实例类型作为泛型,直接复用基类通用方法,无需重复编写基础查询逻辑:
// user.service.ts import BaseService from './base.service'; import { UserModel } from './user.model'; class UserService extends BaseService<UserModel> { constructor() { super(UserModel); } // 业务方法直接复用基类find async getUsers() { return this.find(); } } export default UserService;
使用说明
- 后续新增其他模型的Service时,只需要继承
BaseService并传入对应模型类,即可直接复用所有通用CRUD方法,无需重复编写相同逻辑 - 如果需要自定义返回类型转换,可以在基类扩展通用的类型转换方法,不要在每个子类里重复实现查询逻辑
- 所有异步方法必须添加
async关键字,否则await语法无法正常生效
内容的提问来源于stack exchange,提问作者mayur badodiya
相关产品推荐
相关产品推荐

