tsyringe动态依赖解析问题:类型联合导致注册与解析失败
解决tsyringe动态解析联合类型服务的依赖问题
问题根源
你遇到的错误核心是注册和解析时使用的依赖token不匹配:
- 注册服务时用
container.register(Service1, { useClass: Service1 }),是以Service1类本身作为token; - 但解析时用了
svc.name(字符串"Service1")作为token,tsyringe会将这两个视为完全不同的依赖标识,因此找不到已注册的服务。
联合类型typeof Service1 | Service2本身不会导致解析失败,只是需要额外处理TypeScript的类型检查。
解决方案
方案1:直接用类作为token解析(推荐)
既然注册时用类本身作为token,解析时直接传入类即可,无需转成字符串:
import { container, injectable } from "tsyringe"; class Client { exec(svcNum: number) { console.log("Executing ", svcNum); } } @injectable() class Service1 { private readonly num = 1; constructor(private client: Client) {} serve() { this.client.exec(this.num); } } @injectable() class Service2 { private readonly num = 2; constructor(private client: Client) {} serve() { this.client.exec(this.num); } } // 以类作为token注册服务 container.register(Service1, { useClass: Service1 }); container.register(Service2, { useClass: Service2 }); const services = [Service1, Service2]; services.forEach((svc) => { if (container.isRegistered(svc)) { console.log("Found registered service ", svc.name); } // 直接传入类作为resolve参数 const resolved = container.resolve(svc); resolved.serve(); });
方案2:用字符串作为统一token
如果业务需要用字符串标识服务,注册和解析时要统一使用字符串token:
// 以字符串作为token注册服务 container.register("Service1", { useClass: Service1 }); container.register("Service2", { useClass: Service2 }); // 存储字符串token与对应类的映射 const servicePairs = [["Service1", Service1], ["Service2", Service2]] as const; servicePairs.forEach(([token, svcClass]) => { if (container.isRegistered(token)) { console.log("Found registered service ", token); } const resolved = container.resolve(token) as InstanceType<typeof svcClass>; resolved.serve(); });
类型优化建议
为避免频繁使用as any,可以定义公共接口让所有服务实现:
interface IService { serve(): void; } @injectable() class Service1 implements IService { // 原有代码不变 } @injectable() class Service2 implements IService { // 原有代码不变 } // 解析后直接断言为IService const resolved = container.resolve(svc) as IService; resolved.serve();
内容的提问来源于stack exchange,提问作者Abrar Hossain
相关产品推荐
相关产品推荐

