Angular 16设置TypeScript target为ES2022时依赖注入异常问题
问题原因与解决方案
核心原因
当tsconfig.json的target设为ES2022时,TypeScript会使用原生ECMAScript类字段语法编译类属性,这直接改变了类成员的初始化顺序:
- 在
ES2020及更低目标下,TypeScript会将类字段的初始化代码插入到构造函数内部(在super()调用之后),此时Angular的依赖注入已完成,this指向类实例且注入的依赖(如actions$)已就绪。 - 而
ES2022目标下,类字段会在基类构造函数执行之前初始化。如果你的AppEffects类中,createEffect的定义使用了普通函数而非箭头函数,或者createEffect字段的位置在注入的actions$之前,就会导致初始化createEffect时:this尚未绑定到当前类实例(基类构造函数未执行);- 注入的
actions$还未被赋值到类实例上。
这就解释了为什么调试时构造函数里actions$已定义,但执行createEffect时this为undefined。
解决方案
1. 确保createEffect的回调使用箭头函数
箭头函数会自动绑定当前类实例的this,避免原生类字段语法下的this丢失问题:
// 错误写法:普通函数导致this丢失 loadAppData$ = createEffect(function () { return this.actions$.pipe(/* ... */); }); // 正确写法:箭头函数绑定this loadAppData$ = createEffect(() => { return this.actions$.pipe(/* ... */); });
2. 调整类成员顺序(可选)
如果必须使用普通函数,需确保注入的依赖(如actions$)的定义位置早于所有createEffect字段:
export class AppEffects { // 先定义注入的依赖 constructor(private actions$: Actions) {} // 再定义createEffect字段 loadAppData$ = createEffect(function () { return this.actions$.pipe(/* ... */); }); }
3. 升级NgRx到对应版本的最新补丁
你当前使用的@ngrx/*@16.0.1虽支持Angular 16,但部分早期补丁版本可能存在ES2022目标下的类字段兼容问题,升级到NgRx 16的最新补丁版本(如16.3.0)可修复此类问题。
内容的提问来源于stack exchange,提问作者peterc
相关产品推荐
相关产品推荐

