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

IoC容器resolve方法返回类型的类型推断实现问询

实现IoC容器resolve方法的返回类型自动推断

要让编辑器自动识别resolve方法的返回类型,核心是利用TypeScript的泛型重载和类型追踪能力,通过在bind过程中记录绑定的类型信息,让resolve能根据传入的参数(抽象类型或字符串别名)自动推断出正确的返回类型。以下是具体实现方案:

核心思路

  • 用泛型类型追踪容器内所有绑定的类型映射关系
  • 给bind方法设置重载,分别处理抽象类型(构造函数)和字符串别名的绑定逻辑,同时更新泛型类型
  • 给resolve方法设置重载,根据传入参数的类型(构造函数或字符串别名),从泛型映射中匹配对应的返回类型

完整代码实现

// 定义绑定映射的基础类型,键为字符串或Symbol,值为任意类型
type BindingMap = Record<string | symbol, unknown>;

class MyContainer<B extends BindingMap = {}> {
  // 运行时存储绑定的工厂函数
  private bindings: Map<string | symbol, () => unknown> = new Map();

  // 重载1:绑定抽象类型(构造函数)
  bind<T>(abstractType: new () => T, factory: () => T): MyContainer<B & { [K in symbol as typeof abstractType]: T }>;
  // 重载2:绑定字符串别名
  bind<T>(alias: string, factory: () => T): MyContainer<B & { [K in typeof alias]: T }>;
  // bind方法的具体实现
  bind<T>(key: string | (new () => T), factory: () => T): MyContainer<B> {
    // 用Symbol存储构造函数类型的绑定,避免和字符串别名冲突
    const mapKey = typeof key === 'string' ? key : Symbol.for(key.name);
    this.bindings.set(mapKey, factory);
    // 类型断言更新容器的泛型类型
    return this as unknown as MyContainer<B & { [K in typeof mapKey]: T }>;
  }

  // 重载1:resolve抽象类型,返回对应实例类型
  resolve<T>(abstractType: new () => T): T;
  // 重载2:resolve字符串别名,返回绑定的对应类型
  resolve<K extends keyof B>(alias: K): B[K];
  // resolve方法的具体实现
  resolve<T>(key: string | (new () => T)): T | B[keyof B] {
    const mapKey = typeof key === 'string' ? key : Symbol.for(key.name);
    const factory = this.bindings.get(mapKey);
    
    if (!factory) {
      throw new Error(`未找到绑定:${typeof key === 'string' ? key : key.name}`);
    }

    return factory();
  }
}

关键细节说明

  • 泛型追踪绑定:容器类的泛型B会在每次调用bind时扩展,记录新绑定的类型信息,确保resolve能获取到准确的类型映射。
  • 构造函数的类型处理:用Symbol.for(key.name)作为构造函数绑定的运行时键,避免和字符串别名冲突;类型层面通过typeof abstractType作为泛型映射的键,关联构造函数和其实例类型。
  • 重载的作用:bind和resolve的重载让TypeScript能根据传入参数的类型,自动匹配对应的逻辑并推断返回类型,编辑器就能实时提示正确的类型信息。

使用示例

// 定义抽象类作为抽象类型
abstract class ILogger {
  abstract log(message: string): void;
}

// 实现类
class ConsoleLogger extends ILogger {
  log(message: string) {
    console.log(`日志:${message}`);
  }
}

// 初始化容器并绑定
const container = new MyContainer()
  .bind(ILogger, () => new ConsoleLogger())
  .bind('systemLogger', () => new ConsoleLogger());

// resolve抽象类型,编辑器会识别返回ILogger类型
const logger1 = container.resolve(ILogger);
logger1.log('测试抽象类型绑定');

// resolve字符串别名,编辑器会识别返回ConsoleLogger类型
const logger2 = container.resolve('systemLogger');
logger2.log('测试别名绑定');

内容的提问来源于stack exchange,提问作者Nasa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 10:37:18