尽管声明但不进行数组推送:TS2345:无法将类型为“字符串”的参数分配给类型为“从不”的参数

时间:2019-06-20 10:37:11

标签: typescript array-push

我在标题transactionIds: acc.transactionIds.push(currId)的标题中提到了错误。

我的代码如下:

const resultObject: {
        amountAccumulated: number;
        amountLeft: number;
        rate: number | undefined;
        transactionIds: string[];
    } = arrDocs.reduce(
        (acc, curr, i) => {
            let currData:
                | admin.firestore.DocumentData
                | undefined = curr.data();
            if (currData === undefined) return acc;

            let currId = curr.id;
            let amountLeft: number = acc.amountLeft;
            let amountToAdd: number = Math.min(
                currData.remaining_amount,
                amountLeft
            );

            return {
                amountAccumulated: acc.amountAccumulated + amountToAdd,
                amountLeft: acc.amountLeft - amountToAdd,
                rate: undefined,
                transactionIds: acc.transactionIds.push(currId)
            };
        },
        {
            amountAccumulated: 0,
            amountLeft: spentAmount.amount,
            rate: undefined,
            transactionIds: []
        }
    );

我不知道为什么会出错。有人有主意吗? 我在网上阅读到我应该只声明数组(我认为我已经完成了resultObject的声明)。

编辑: 当我使用传播运算符实现建议的更改时,收到以下错误:

TS2345: Argument of type '(acc: { amountAccumulated: number; amountLeft: number; rate: undefined; transactionIds: never[]; ...' is not assignable to parameter of type '(previousValue: { amountAccumulated: number; amountLeft: number; rate: undefined; transactionIds:...'.
      Type '{ amountAccumulated: number; amountLeft: number; rate: undefined; transactionIds: string[]; }' is not assignable to type '{ amountAccumulated: number; amountLeft: number; rate: undefined; transactionIds: never[]; }'.
        Types of property 'transactionIds' are incompatible.
          Type 'string[]' is not assignable to type 'never[]'.
            Type 'string' is not assignable to type 'never'.

代码在这里:

return {
     amountAccumulated: acc.amountAccumulated + amountToAdd,
     amountLeft: acc.amountLeft - amountToAdd,
     rate: undefined,
     transactionIds: [...acc.transactionIds, currId]
 };

1 个答案:

答案 0 :(得分:2)

我无法解释为什么错误完全说明了问题,但该行不正确。 push返回数字,而不是数组,但是transactionIds应该是数组。

如果您想每次都创建一个新对象,则可以散布现有的事务ID并添加新的事务ID,如下所示:

transactionIds: [...acc.transactionIds, currId]

您已经说过要使它正常工作很困难,并且TypeScript仍在抱怨never[]数组。由于您需要TypeScript来推断累加器的transactionIds类型,所以我想它一定在推断错误。

我要定义一个类型:

interface ResultType {
    amountAccumulated: number;
    amountLeft: number;
    rate: number | undefined;
    transactionIds: string[];
}

,然后在为累加器提供的对象上使用它,以便TypeScript清楚transactionIds的类型是什么:

const resultObject: ResultType = arrDocs.reduce(
    (acc, curr, i) => {
        // ...
    },
    <ResultType>{
        amountAccumulated: 0,
        amountLeft: spentAmount.amount,
        rate: undefined,
        transactionIds: []
    }
);

请注意,为此使用reduce并没有使它更加复杂。您还会有很多多余的类型注释,TypeScript非常乐意(正确)进行推断。这是我的处理方法:

首先,我要输入一个类型(尽管如果您不想这样做,则不必这样做):

interface ResultType {
    amountAccumulated: number;
    amountLeft: number;
    transactionIds: string[];
    rate: number | undefined;
}

然后我会这样:

let amountAccumulated = 0;
let amountLeft = 0;
let transactionIds: string[] = [];
for (const curr of arrDocs) {
    let currData = curr.data();
    if (currData !== undefined) {
        let amountToAdd = Math.min(
            currData.remaining_amount,
            acc.amountLeft
        );
        amountAccumulated += amountToAdd;
        amountLeft -= amountToAdd;
        transactionIds.push(curr.id);
    }
}
const resultObject: ResultType = {
    amountAccumulated,
    amountLeft,
    rate: undefined,
    transactionIds
};

如果您不想拥有类型,只需在创建对象的最后一条语句中将其替换:

const resultObject: {
    amountAccumulated: number;
    amountLeft: number;
    transactionIds: string[];
    rate: number | undefined;
} = {
    amountAccumulated,
    amountLeft,
    rate: undefined,
    transactionIds
};