升级ngrx 2至4:解构数组时遭遇类型错误问题
Hey there! Let's work through these two bugs you hit upgrading NgRx from v2 to v4—this version jump had some big API shifts that catch a lot of people off guard.
1. The ".map" Comma Required Error
First off, that comma prompt in your .map operator is likely tied to NgRx v4’s stricter type checking and small syntax shifts in how we write Effects.
In NgRx v2, you might have had code like this, where you directly return an action via .map():
@Effect() addData$ = this.actions$ .ofType(DataActions.ADD_DATA) .map(action => { // Process your data here return new DataActions.AddDataSuccess(processedData); });
But in v4, if you’re adding type annotations to the action parameter, you need to wrap it in parentheses—otherwise TypeScript throws a syntax/type error that might manifest as a "comma required" prompt. For example:
// ❌ Wrong (triggers type/syntax issues) .map(action: DataActions.AddDataAction => { ... }) // ✅ Correct .map((action: DataActions.AddDataAction) => { ... })
Also, double-check that you’ve imported all necessary RxJS operators—v4 started leaning into lettable operators, so make sure you have imports like import 'rxjs/add/operator/map'; or (if using newer RxJS syntax) import { map } from 'rxjs/operators'; and pipe it properly.
2. Tuple Mismatch for DataActions.AddDataAction
This is a classic breaking change between NgRx v2 and v4. Back in v2, you could pass dependencies directly to the @Effect() decorator as a tuple—like @Effect([Action, AppStore])—but v4 completely changed how dependency injection works for Effects.
The error saying a length-2 tuple [Action, AppStore] can’t be assigned to a length-5 tuple comes because v4’s @Effect() decorator now expects an optional configuration object (not a dependency array). TypeScript is trying to force your old v2 syntax into the new type signature, which doesn’t fit.
Here’s how to fix it:
- Remove any dependency tuple from the
@Effect()decorator entirely. - Inject your
AppStore(or other dependencies) into the Effect class constructor instead:
// ✅ NgRx v4 Correct Syntax @Injectable() export class DataEffects { // Inject dependencies here via constructor constructor( private actions$: Actions, private appStore: AppStore ) {} @Effect() // No dependencies passed here addData$ = this.actions$ .ofType(DataActions.ADD_DATA) .map((action: DataActions.AddDataAction) => { // Use this.appStore if you need access to the store return new DataActions.AddDataSuccess(yourPayload); }); }
Also, make sure your AddDataAction follows v4’s action conventions—define it as a class with a readonly type property:
export class AddDataAction implements Action { readonly type = DataActions.ADD_DATA; constructor(public payload: YourDataType) {} }
Quick Package Version Check
Since you mentioned your package.json, ensure you’re on compatible NgRx v4 versions (mixed versions often cause type mismatches):
{ "@ngrx/store": "^4.1.1", "@ngrx/effects": "^4.1.1", "rxjs": "^5.5.0" // RxJS 5.5+ is required for NgRx v4 }
内容的提问来源于stack exchange,提问作者qbolt

