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

Angular/TypeScript中能否在Mixin中使用依赖注入?

能否在TypeScript/Angular的Mixin中使用依赖注入?

现有代码

export const MyMixin = <T extends Type<MyClass>>(Base: T): T =>
  class extends Base {
    constructor(...args: any[]) {
      super(...args);
    }
  };

尝试添加依赖后的代码

需要给Mixin添加依赖Service的myMethod(),修改后代码如下:

export const MyMixin = <T extends Type<MyClass>>(Base: T): T =>
    class extends Base {
      constructor(private injector: Injector, ...args: any[]) { // 👈 触发TS错误(2545)
        super(...args);
        this.myMethod();
      }

      private myMethod(): void {
        this.injector.get(SomeService).doSomething();
      };
    };

TypeScript报错信息

A mixin class must have a constructor with a single rest parameter of type 'any[]'.ts(2545)

此前有类似问题,现有方案是为全局类提供Injector,但属于反模式,现寻求Mixin中实现“干净”依赖注入的方案。


解决方案:符合规则的干净实现方式

方案1:利用父类注入的服务实例

确保父类MyClass已注入所需服务,Mixin直接通过继承链访问父类的服务实例,完全遵循TypeScript的Mixin构造函数规则:

// 父类MyClass
export class MyClass {
  constructor(protected someService: SomeService) {}
}

// Mixin实现
export const MyMixin = <T extends Type<MyClass>>(Base: T): T =>
  class extends Base {
    constructor(...args: any[]) {
      super(...args);
      this.myMethod();
    }

    private myMethod(): void {
      this.someService.doSomething();
    }
  };

方案2:从构造函数参数中提取Injector

如果父类已注入Injector,可以从Mixin构造函数的rest参数中提取该实例,避免修改构造函数签名:

import { Injector, Type } from '@angular/core';

export const MyMixin = <T extends Type<MyClass>>(Base: T): T =>
  class extends Base {
    private injector: Injector;

    constructor(...args: any[]) {
      super(...args);
      // 从父类构造参数中筛选出Injector实例
      this.injector = args.find(arg => arg instanceof Injector) as Injector;
      this.myMethod();
    }

    private myMethod(): void {
      const someService = this.injector.get(SomeService);
      someService.doSomething();
    }
  };

方案3:将服务作为Mixin参数传入

定义Mixin时直接接收所需服务实例,把注入逻辑移到Mixin外部,保持Mixin的纯净性:

import { Type } from '@angular/core';
import { SomeService } from './some.service';

export const MyMixin = <T extends Type<MyClass>>(Base: T, someService: SomeService): T =>
  class extends Base {
    constructor(...args: any[]) {
      super(...args);
      this.myMethod(someService);
    }

    private myMethod(someService: SomeService): void {
      someService.doSomething();
    }
  };

使用时在组件/类中注入服务后传入Mixin:

@Component({...})
export class MyComponent extends MyMixin(MyClass, someService) {
  constructor(private someService: SomeService) {
    super(someService);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 00:55:02