NestJS+TypeORM泛型仓库模式报错:repository方法不是函数
问题分析与解决
错误根源
你的代码存在两个关键问题:
- 模块配置逻辑错误:
TodoModule里TypeOrmModule.forFeature错误注册了TodoRepository而非实体Todo,同时providers配置中将Todo实体当作TodoRepository的实现类注入,导致服务中拿到的是Todo实例而非自定义仓库实例,自然找不到findAll方法。 - 自定义仓库未被Nest管理:
TodoRepository缺少@Injectable()装饰器,Nest无法处理其依赖注入逻辑。
修正步骤
1. 修复todo.repository.ts
给TodoRepository添加@Injectable()装饰器,让Nest能够识别并管理这个类的依赖:
import { Repository } from 'typeorm'; import { IRepository } from './todo.interface'; import { Injectable } from '@nestjs/common'; @Injectable() // 添加该装饰器 export class TodoRepository<T> implements IRepository<T> { constructor(private repository: Repository<T>) { } async createTodo(item: T): Promise<T> { return await this.repository.save(item); } async findAll(): Promise<T[]> { return await this.repository.find(); } async update(id: string, item: T): Promise<T> { const updatedItem = await this.repository.preload({ id: id, ...item, }); return await this.repository.save(updatedItem); } async delete(id: string): Promise<boolean> { const result = await this.repository.delete(id); return result.affected === 1; } call() { return "call methods"; } }
2. 修复todo.module.ts
调整TypeOrmModule.forFeature注册实体Todo,并正确配置TodoRepository的提供者,注入TypeORM原生的Repository<Todo>:
import { Module } from '@nestjs/common'; import { TodoController } from './todo.controller'; import { TodoService } from './todo.service'; import { TypeOrmModule, getRepositoryToken } from '@nestjs/typeorm'; import { Todo } from './todo.entity'; import { TodoRepository } from './todo.repository'; @Module({ imports: [TypeOrmModule.forFeature([Todo])], // 注册实体Todo controllers: [TodoController], providers: [ TodoService, { provide: TodoRepository, useFactory: (todoRepo: Repository<Todo>) => new TodoRepository(todoRepo), inject: [getRepositoryToken(Todo)], // 获取Todo实体对应Repository的注入标识 } ] }) export class TodoModule { }
3. 验证效果
此时TodoService中注入的todoRepository已经是正确的TodoRepository<Todo>实例,调用findAll()等方法不会再出现报错。
逻辑说明
TypeOrmModule.forFeature([Todo])会让Nest创建并注入对应实体的原生Repository实例。- 通过
useFactory我们将原生Repository传入自定义的TodoRepository,实现泛型仓库的逻辑封装。 getRepositoryToken(Todo)用来获取对应实体的Repository注入标识,确保能正确拿到原生Repository实例。
内容的提问来源于stack exchange,提问作者Aniket Dutta
相关产品推荐
相关产品推荐

