NGRX reducer 问题:"X" 类型的参数不可分配给 "Y" 类型的参数

NGRX reducer problem : Argument of type "X" is not assignable to parameter of type "Y"

使用 ngrx 成功编译 angular 应用构建后出现错误。

ERROR in src/app/store/cart-items.reducer.ts:17:62 - error TS2345: Argument of type '{ items: CartItem[]; bestCommercialOfferValue: number; }' is not assignable to parameter of type 'CartItemsState'.
  Property 'commercialOffers' is missing in type '{ items: CartItem[]; bestCommercialOfferValue: number; }' but required in type 'CartItemsState'.

17     on(DeleteCartItem, (state, action) => (deleteReturnState(state, action.isbn))),
                                                                ~~~~~

  src/app/store/cartItemsState.ts:7:5
    7     commercialOffers: CommercialOffer[];
          ~~~~~~~~~~~~~~~~
    'commercialOffers' is declared here.
src/app/store/cart-items.reducer.ts:18:73 - error TS2345: Argument of type '{ items: CartItem[]; bestCommercialOfferValue: number; }' is not assignable to parameter of type 'CartItemsState'.

18     on(UpdateQuantityToBuyCartItem, (state, action) => (GetUpdatedState(state, action.cartItem))),
                                                                           ~~~~~

在相关状态对象上添加字段 commercialOffers 后,此错误出现在特定的减速器文件 cart-item.reducer.ts 中。

import { CartItem } from '../models/cartItem';
import { CommercialOffer } from '../models/commercialOffer';

export interface CartItemsState {
    items: CartItem[];
    bestCommercialOfferValue: number;
    commercialOffers: CommercialOffer[];
}

相关的 reducer 文件如下所示:

import { Action, createReducer, on } from '@ngrx/store';
import { CartItem } from '../models/cartItem';
import { CommercialOffer } from '../models/commercialOffer';
import { AddCartItem, DeleteCartItem, UpdateQuantityToBuyCartItem, ClearCart, ApiGetCommercialOffersSuccess } from './actions';
import { CartItemsState } from './cartItemsState';


export const initialState: CartItemsState = {
    items: [],
    bestCommercialOfferValue: 0,
    commercialOffers: []
};

const _cartItemsReducer = createReducer(
    initialState,
    on(AddCartItem, (state, action) => ({ items: [...state.items, action.data], bestCommercialOfferValue: state.bestCommercialOfferValue })),
    on(DeleteCartItem, (state, action) => (deleteReturnState(state, action.isbn))),
    on(UpdateQuantityToBuyCartItem, (state, action) => (GetUpdatedState(state, action.cartItem))),
    on(ClearCart, (state, action) => ({ items: [], bestCommercialOfferValue: 0, commercialOffers: [] })),
    on(ApiGetCommercialOffersSuccess, (state, action) => ({ items: state.items, bestCommercialOfferValue: getBestCommercialOffer(state.items, action.commercialOffers) })));

function getBestCommercialOffer(actualCartItems: CartItem[], bunchOfCommercialOffers: CommercialOffer[]): number {

const subTotal = actualCartItems.reduce((sum, current) => sum + current.bookInfos.price * current.quantityToBuy, 0);
const reductionValues: number[] = [];

bunchOfCommercialOffers.forEach(actualCommercialOffer => {
    if (actualCommercialOffer.type == "percentage") {
        reductionValues.push(actualCommercialOffer.value);
    } else if (actualCommercialOffer.type == "minus") {
        reductionValues.push(actualCommercialOffer.value);
    } else if (actualCommercialOffer.type == "slice") {
        const sliceValue = actualCommercialOffer.sliceValue;
        const reductionValue = actualCommercialOffer.value;
        const multiply = Math.trunc(subTotal / sliceValue);

        reductionValues.push(reductionValue * multiply);
    }});

    return reductionValues.reduce((previousValue, actualValue) => previousValue = previousValue > actualValue ? previousValue : actualValue, 0);}


function deleteReturnState(actualCartItemsState: CartItemsState, isbn: string): CartItemsState {
    return {
        items: actualCartItemsState.items.filter(item => item.bookInfos.isbn != isbn),
        bestCommercialOfferValue: actualCartItemsState.bestCommercialOfferValue,
        commercialOffers: actualCartItemsState.commercialOffers
    }
}

function GetUpdatedState(actualCartItemsState: CartItemsState, cartItemToUpdate: CartItem): CartItemsState {
    const newList: CartItem[] = [];

    actualCartItemsState.items.forEach(cartItem => {

    const newCartItem = <CartItem>{
        bookInfos: cartItem.bookInfos,
        quantityToBuy: cartItem.quantityToBuy
    }

    if (cartItem.bookInfos.isbn == cartItemToUpdate.bookInfos.isbn) {
        newCartItem.quantityToBuy = cartItemToUpdate.quantityToBuy;
    }

    newList.push(newCartItem)})

    return {
        items: newList,
        bestCommercialOfferValue: actualCartItemsState.bestCommercialOfferValue,
        commercialOffers: actualCartItemsState.commercialOffers
    }}

export function cartItemsReducer(state: CartItemsState | undefined, action: Action) {
    return _cartItemsReducer(state, action);
}

奇怪的是,即使出现此错误,我的应用程序也可以 运行 完美。

您似乎在操作中包含了参数 commercialOffers。您需要在对象中包含此 属性 才能使错误消失。另一个选项如下,如果参数是可选的,那么你可以像

这样声明你的接口
export const initialState: CartItemsState = {
    items: [],
    bestCommercialOfferValue: 0,
    commercialOffers?: []
};

注意 commercialOffers?: [] 中的 ? 表示此参数是可选的