TypeScript基于接口实现依赖注入并配置默认仓储的问题咨询
报错原因
你遇到的TS2351错误本质是类型定义混淆:IUsersRepository是实例接口,仅描述仓储类实例的属性、方法结构,不代表仓储类本身的构造类型。你在构造函数参数中声明ReceivedUsersRepository: IUsersRepository | null,相当于要求传入已经实例化完成的仓储对象,后续再执行new ReceivedUsersRepository()自然会报错——实例对象不能被二次实例化。
最优实现方案(推荐)
直接传已经实例化的仓储对象,默认值设置为默认仓储的实例,这是最符合依赖注入常规实践的写法,逻辑简单直观,灵活性更高:
import UsersRepository from './UsersRepository'; import type { IUsersRepository } from './你的接口文件路径'; class UsersUseCases{ private userRepository: IUsersRepository; // 直接把默认实例写在参数默认值位置 constructor(userRepository: IUsersRepository = new UsersRepository()) { this.userRepository = userRepository; } /** 其他业务方法 **/ }
用法示例
- 正式环境使用:不需要传任何参数,自动用默认的
UsersRepositoryconst userUseCase = new UsersUseCases(); - 测试环境使用:自行实现mock仓储,传入实例即可
// 测试用Mock实现 class MockUsersRepository implements IUsersRepository { async createUser(email: string, password: string) { // 替换为测试用假逻辑 return { id: 1, email }; } } // 测试时传入Mock实例 const testUseCase = new UsersUseCases(new MockUsersRepository());
可选方案:传入类而非实例
如果你有特殊需求需要在UsersUseCases内部控制仓储的实例化时机,可以先定义构造函数类型,再传入类本身:
- 先在
IUsersRepository所在文件新增构造类型定义:export interface IUsersRepository { createUser(email: string, password: string): Promise<any>; } // 新增:描述可实例化出IUsersRepository的类的类型 export interface IUsersRepositoryConstructor { new (): IUsersRepository; } - 修改
UsersUseCases代码:import UsersRepository from './UsersRepository'; import type { IUsersRepository, IUsersRepositoryConstructor } from './你的接口文件路径'; class UsersUseCases{ private userRepository: IUsersRepository; constructor(RepositoryClass: IUsersRepositoryConstructor = UsersRepository) { this.userRepository = new RepositoryClass(); } /** 其他业务方法 **/ }
用法示例
- 正式环境使用:不需要传任何参数,内部自动实例化
UsersRepositoryconst userUseCase = new UsersUseCases(); - 测试环境使用:直接传入Mock类即可,无需提前实例化
class MockUsersRepository implements IUsersRepository { async createUser(email: string, password: string) { return { id: 1, email }; } } const testUseCase = new UsersUseCases(MockUsersRepository);
内容的提问来源于stack exchange,提问作者yuridamata
相关产品推荐
相关产品推荐

