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?: []
中的 ?
表示此参数是可选的
使用 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?: []
中的 ?
表示此参数是可选的