【问题标题】:Source has 2 element(s) but target allows only 1. Typescript spread operator源有 2 个元素,但目标只允许 1 个。Typescript 扩展运算符
【发布时间】:2025-12-11 13:00:01
【问题描述】:

我正在尝试在数组中传播所有值并在我的减速器中附加一个新对象。

我的状态界面

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添加item功能:

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;
};

当我将鼠标悬停在 ...basketState.products 上时,我收到一条错误消息:

输入 '[{ id: number |不明确的;名称:字符串;小Q:数字; smallTotalP:数字;大Q:数字; largeTotalP:数字;订单价格:数量; }, { id: 数字 |不明确的;名称:字符串;小Q:数字; smallTotalP:数字;大Q:数字; largeTotalP:数字;订单价格:数量; }]' 不能分配给类型 '[{ id: number |不明确的;名称:字符串;小Q:数字; smallTotalP:数字;大Q:数字; largeTotalP:数字;订单价格:数量; }]'。

来源有 2 个元素,但目标只允许 1.ts(2322)

BasketContext.tsx(8, 2):预期的类型来自属性“products”,在此处声明的类型为“IBasketState”

问题是在我的界面中我只在 products 数组中声明了一个对象而我现在尝试拥有 2 个吗?如果是这样,我该如何绕过它?

【问题讨论】:

标签: javascript reactjs typescript ecmascript-6


【解决方案1】:

您的猜测是正确的:products 属性被键入为一个仅包含一个元素的元组。

您可以尝试将其变成一系列产品:

interface BasketState {
    products: Product[];
    totalPrice: number;
}

interface Product {
    id: number | undefined;
    name: string;
    smallQ: number;
    smallTotalP: number;
    largeQ: number;
    largeTotalP: number;
    orderPrice: number;
}

您可以在此处阅读有关 TypeScript 元组类型的更多信息:https://www.typescriptlang.org/docs/handbook/2/objects.html#tuple-types

【讨论】:

    【解决方案2】:

    您已将 products 声明为具有单个对象 ([T]) 的元组,而不是列表 (T[]Array<T>)。所以换句话说,你想要的是:

    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;
    }
    

    有时,定义项目的类型而不是列表会更好,这样您的界面就可以如下所示:

    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;
    }
    

    【讨论】:

    • 非常感谢!我刚刚学习 TypeScript,这帮助我理解了这个问题。