Angular中是否可以使用带泛型类型的服务?具体该如何实现?
问题根因
TypeScript的泛型属于编译期语法,编译为JavaScript后泛型参数会被完全擦除,Angular的依赖注入系统运行时无法通过GenericService<ExampleUpdaterService>这个类型判断需要注入的TService对应的具体实例,因此会抛出注入失败的错误。
解决方案
根据使用场景可以选择以下两种方案:
方案1:派生具体服务类(推荐,适用固定泛型组合场景)
直接为你需要的泛型组合创建一个可被Angular DI识别的派生服务类,无需额外配置注入令牌:
- 首先移除
GenericService的providedIn: 'root'配置,因为它作为泛型基类不需要全局注册实例:
// 调整后的泛型服务 @Injectable() export class GenericService<TService extends IUpdater> { constructor(private service: TService) { } // 其他业务代码 }
- 创建派生服务,指定泛型参数:
@Injectable({ providedIn: "root" }) export class ExampleGenericService extends GenericService<ExampleUpdaterService> { constructor(updater: ExampleUpdaterService) { super(updater); } }
- 组件中直接注入派生服务即可:
@Component({ /* 其他组件配置 */ }) export class TdeComponent implements OnInit { constructor(private updaterService: ExampleGenericService) { } }
方案2:注入令牌+工厂函数(适用动态泛型组合场景)
如果需要在不同位置灵活搭配不同的IUpdater实现,可通过注入令牌+工厂函数的方式动态生成实例:
- 定义泛型注入令牌与工厂函数:
import { InjectionToken, Inject } from '@angular/core'; export const GENERIC_SERVICE = new InjectionToken<GenericService<IUpdater>>('GENERIC_SERVICE'); export function createGenericService<T extends IUpdater>(service: T) { return new GenericService(service); }
- 在组件的providers中配置对应注入规则:
@Component({ /* 其他组件配置 */ providers: [ ExampleUpdaterService, { provide: GENERIC_SERVICE, useFactory: (updater: ExampleUpdaterService) => createGenericService(updater), deps: [ExampleUpdaterService] } ] }) export class TdeComponent implements OnInit { constructor(@Inject(GENERIC_SERVICE) private updaterService: GenericService<ExampleUpdaterService>) { } }
内容的提问来源于stack exchange,提问作者M. Akar
相关产品推荐
相关产品推荐

