参数“动作”和“动作”的类型不兼容,Angular ngrx 中缺少属性“有效载荷”

问题描述

我是 angular 的新手。在这里,我使用 ngrx 来管理我的 angular 应用程序中的状态。但是当我编译时出现以下错误。它说'参数'动作'和'动作'的类型不兼容'。我想知道这是什么原因以及如何解决

 
    Error: src/app/shopping-list/store/shoppingList.actions.ts:9:5 - error TS2564: Property 'payload' has no initializer and is not definitely assigned in the constructor.
    
    9     payload: Ingredient;
          ~~~~~~~
    src/app/app.module.ts:25:27 - error TS2322: Type '(state: { ingredients: Ingredient[]; } | undefined,action: AddIngredient) => { ingredients: Ingredient[]; }' is not assignable to type 'ActionReducer<{ ingredients: Ingredient[]; },Action>'.
      Types of parameters 'action' and 'action' are incompatible.
        Property 'payload' is missing in type 'Action' but required in type 'AddIngredient'.
    
    25     StoreModule.forRoot({ shoppingList: shoppingListReducer }),~~~~~~~~~~~~
    
      src/app/shopping-list/store/shoppingList.actions.ts:9:5
        9     payload: Ingredient;
              ~~~~~~~
        'payload' is declared here.

这是我的 shoppingList.actions.ts 文件

import { Action } from '@ngrx/store'

import { Ingredient } from '../../shared/ingredient.model';

export const ADD_INGREDIENT = 'ADD_INGREDIENT';

export class AddIngredient implements Action {
    readonly type = ADD_INGREDIENT;
    payload: Ingredient;
}

这是shoppingList.reducer.ts 文件


import { Ingredient } from "src/app/shared/ingredient.model";

import * as shoppingListActions from './shoppingList.actions';

const intialState = {
    ingredients: [
        new Ingredient("Apples",3),new Ingredient("Tomatoes",4)
    ]
}

export function shoppingListReducer(state = intialState,action: shoppingListActions.AddIngredient) {
    switch (action.type) {
        case shoppingListActions.ADD_INGREDIENT:
            return {
                ...state,ingredients: [...state.ingredients,action.payload]
            }
        default:
            return state;
    }
}

这是我的 app.module.ts 文件

import { browserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRouting } from './app-routing.module';
import { FormsModule,ReactiveFormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { StoreModule } from '@ngrx/store';

import { AppComponent } from './app.component';
import { HeaderComponent } from './header/header.component';
import { SharedModule } from './shared/shared.module';
import { CoreModule } from './core.module';
import { shoppingListReducer } from './shopping-list/store/shoppingLis.reducer';

@NgModule({
  declarations: [
    AppComponent,HeaderComponent,],imports: [
    browserModule,FormsModule,ReactiveFormsModule,HttpClientModule,StoreModule.forRoot({ shoppingList: shoppingListReducer }),AppRouting,SharedModule,CoreModule,bootstrap: [AppComponent]
})
export class AppModule { }

解决方法

你的问题是因为签名问题,

Method StoreModule.forRoot(reducers: ActionReducerMap)

从技术上讲,您传递的是正确的参数,但仍然说您的 Action 对象参数包含一个字段调用 payload,而 Action 中不存在该字段调用ActionReducerMap 的 strong> 参数。从技术上讲,它不应该是错误,因为您已经将 Action 继承到您的操作类

类 AddIngredient 实现 Action{

但不幸的是,ActionReducerMap 中的 Action 显然不是 来自 '@ngrx/store' 或者它们不相同,因此给出编译错误。

由于您没有任何其他选择,您必须按照以下方式修复它:-

首先在 shopping-list.reducer.ts

中创建如下所示的 State
export interface ShoppingListState{
    ingredients: Ingredient[];
}

const initialState: ShoppingListState = {
    ingredients: [
        new Ingredient('Apples',5),new Ingredient("Tomatoes",4),]
};

同时修改你的reducer方法,如下所示:-

export function shoppingListReducer(state: ShoppingListState = initialState,action: shoppingListActions.AddIngredient): ShoppingListState {
    switch(action.type){

现在在您的操作文件夹下创建一个文件调用 index.ts(在减速器文件的同一位置 - 您也可以提供不同的名称),如下所示

import { ShoppingListState,shoppingListReducer } from './shopping-list.reducer';
import { ActionReducerMap } from '@ngrx/store';


export const rootReducer = {};

export interface AppState {
    shoppingList: ShoppingListState;
};


export const reducers: ActionReducerMap<AppState,any> = {
    shoppingList: shoppingListReducer
};

现在将此减速器导入您的app.module.ts

import { reducers } from './reducers/'

并修改您的代码,如下所示

StoreModule.forRoot(reducers)

也尽量避免像下面这样声明变量。

payload: Ingredient;

最好使用构造函数并修改您的代码,如下所示:-

export class AddIngredient implements Action {
    readonly type = ADD_INGREDIENT;
    constructor(public payload: Ingredient){}
}

希望这能解决您的问题。