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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 04:01:06