I'm trying to spread all values in array and append a new object in my reducer.
my state interface:
export interface IBasketState {
products: [
{
id: number | undefined;
name: string;
smallQ: number; //small packages quantity
smallTotalP: number; //price for all small packages
largeQ: number; //large packages quantity
largeTotalP: number; //price for all large packages
orderPrice: number; //total price of this order
}
];
totalPrice: number;
}
Reducer add item function:
const BasketReducer = (basketState: IBasketState, action: IBasketAction): IBasketState => {
//ADD ITEM
if (action.type === "Add item") {
const { id, name, smallQ, smallP, largeQ, price } = action.payload;
let smallTotalPrice = smallQ * smallP; //total price for small packages
let largeTotalPrice = largeQ * price; //total price for large packages
const orderPrice = smallTotalPrice + largeTotalPrice; //total price of this order
return {
products: [
...basketState.products, //--> **THIS IS NOT WORKING**
{
id: id,
name: name,
smallQ: smallQ,
smallTotalP: smallTotalPrice,
largeQ: largeQ,
largeTotalP: largeTotalPrice,
orderPrice: orderPrice,
},
],
totalPrice: basketState.totalPrice + orderPrice,
};
}
//Default action
return basketState;
};
When I hover over ...basketState.products
I've got an error saying:
Type '[{ id: number | undefined; name: string; smallQ: number; smallTotalP: number; largeQ: number; largeTotalP: number; orderPrice: number; }, { id: number | undefined; name: string; smallQ: number; smallTotalP: number; largeQ: number; largeTotalP: number; orderPrice: number; }]' is not assignable to type '[{ id: number | undefined; name: string; smallQ: number; smallTotalP: number; largeQ: number; largeTotalP: number; orderPrice: number; }]'.
Source has 2 element(s) but target allows only 1.ts(2322)
BasketContext.tsx(8, 2): The expected type es from property 'products' which is declared here on type 'IBasketState'
Is the problem the fact that in my interface I have declared only one object in products array and I'm trying to have 2 now? If so how can I bypass that?
I'm trying to spread all values in array and append a new object in my reducer.
my state interface:
export interface IBasketState {
products: [
{
id: number | undefined;
name: string;
smallQ: number; //small packages quantity
smallTotalP: number; //price for all small packages
largeQ: number; //large packages quantity
largeTotalP: number; //price for all large packages
orderPrice: number; //total price of this order
}
];
totalPrice: number;
}
Reducer add item function:
const BasketReducer = (basketState: IBasketState, action: IBasketAction): IBasketState => {
//ADD ITEM
if (action.type === "Add item") {
const { id, name, smallQ, smallP, largeQ, price } = action.payload;
let smallTotalPrice = smallQ * smallP; //total price for small packages
let largeTotalPrice = largeQ * price; //total price for large packages
const orderPrice = smallTotalPrice + largeTotalPrice; //total price of this order
return {
products: [
...basketState.products, //--> **THIS IS NOT WORKING**
{
id: id,
name: name,
smallQ: smallQ,
smallTotalP: smallTotalPrice,
largeQ: largeQ,
largeTotalP: largeTotalPrice,
orderPrice: orderPrice,
},
],
totalPrice: basketState.totalPrice + orderPrice,
};
}
//Default action
return basketState;
};
When I hover over ...basketState.products
I've got an error saying:
Type '[{ id: number | undefined; name: string; smallQ: number; smallTotalP: number; largeQ: number; largeTotalP: number; orderPrice: number; }, { id: number | undefined; name: string; smallQ: number; smallTotalP: number; largeQ: number; largeTotalP: number; orderPrice: number; }]' is not assignable to type '[{ id: number | undefined; name: string; smallQ: number; smallTotalP: number; largeQ: number; largeTotalP: number; orderPrice: number; }]'.
Source has 2 element(s) but target allows only 1.ts(2322)
BasketContext.tsx(8, 2): The expected type es from property 'products' which is declared here on type 'IBasketState'
Is the problem the fact that in my interface I have declared only one object in products array and I'm trying to have 2 now? If so how can I bypass that?
Share Improve this question asked Jul 2, 2021 at 10:44 MadGripMadGrip 4716 silver badges21 bronze badges 1- 1 Does this help stackoverflow./questions/64308563/… ? – Tushar Shahi Commented Jul 2, 2021 at 10:47
2 Answers
Reset to default 5Your guess is correct: the products
property is typed as a tuple containing exactly one element.
What you could try is to turn it into an array of products:
interface BasketState {
products: Product[];
totalPrice: number;
}
interface Product {
id: number | undefined;
name: string;
smallQ: number;
smallTotalP: number;
largeQ: number;
largeTotalP: number;
orderPrice: number;
}
You can read more on the tuple types in TypeScript here: https://www.typescriptlang/docs/handbook/2/objects.html#tuple-types
You have declared products
as a tuple with a single object ([T]
), instead of a list (T[]
or Array<T>
). So in other words, what you want is:
export interface IBasketState {
products: Array<{
id: number | undefined;
name: string;
smallQ: number; //small packages quantity
smallTotalP: number; //price for all small packages
largeQ: number; //large packages quantity
largeTotalP: number; //price for all large packages
orderPrice: number; //total price of this order
}>;
totalPrice: number;
}
Sometimes, it can be nicer to define the type of the item instead of the list, so that your interface can look like this:
export interface IProduct = {
id: number | undefined;
name: string;
smallQ: number; //small packages quantity
smallTotalP: number; //price for all small packages
largeQ: number; //large packages quantity
largeTotalP: number; //price for all large packages
orderPrice: number; //total price of this order
}
export interface IBasketState {
products: IProduct[];
totalPrice: number;
}