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
相关产品推荐
相关产品推荐

