Возможно ли иметь другой тип для предыдущего значения и текущего значения?

#javascript

Вопрос:

У меня есть этот код:

 totalPrice = Object.entries(
  buyTicketData.pricingAndInvoicingType ==
    PricingAndInvoicingType.invoiceItems
    ? buyTicketData.invoiceItems
    : buyTicketData.pricingOptions[startPaymentIn?.pricingOptionId]
        .invoiceItems
).reduce((newObj, [key, val]) => {
  (cumulativValue, ii) => {
    const ret =
      cumulativValue  
      (val.quantity ?? startPaymentIn?.invoiceItems[key] ?? 0) *
        parseInt(val.unitPrice);
    return ret;
  };
}, 0);
 

В моем понимании preiousValue это кумулятивное значение, и оно может быть разным по типу с. currentValue В моем случае previousValue это поля с числом и current value is an array with a and значением ключа.

Но это не работает, что-то работает, может быть, весь подход неправильный. А ты как думаешь?

 ./pages/hu/buyTicket/[eventId].tsx:75:5
Type error: Type '[string, InvoiceItemData]' is not assignable to type 'string'.

  73 |       startPaymentIn?.pricingOptionId)
  74 |   ) {
> 75 |     totalPrice = Object.entries(
     |     ^
  76 |       buyTicketData.pricingAndInvoicingType ==
  77 |         PricingAndInvoicingType.invoiceItems
  78 |         ? buyTicketData.invoiceItems
error Command failed with exit code 1.
 

Ответ №1:

Я думаю, что вы ничего не возвращаете внутри функции уменьшения. Для функции Reduce требуется возвращаемое значение, и это возвращаемое значение передается в предыдущее значение на следующей итерации. Таким образом, на этом этапе он накапливается, потому что он обрабатывает и возвращает данные, используя в качестве предыдущего значения значение следующей итерации. Так что попробуйте вернуть что-нибудь внутри него. Кроме того, я думаю, что вы используете typescript, поэтому я рекомендую вам вставить некоторые типы defs в функцию уменьшения.

Ответ №2:

Object.entries превращает объект в список пар ключ-значение.

Например:

 let invoiceItems = {
  'key-1': 100,
  'key-2': 200,
};

Object.entries(invoiceItems); // [['key-1', 100], ['key-2', 200]]
 

Если теперь вы хотите уменьшить этот список, первые два аргумента функции обратного вызова reduce будут:

  1. аккумулятор (если вы хотите рассчитать сумму чего-то, это будет а number )
  2. каждый элемент списка, в моем примере они имеют тип [string, number]

Чтобы развить свой пример, я мог бы сложить все значения вместе:

 let totalPrice = Object.entries(invoiceItems).reduce(
  (cumulativeValue, [key, val]) => {
    // in my case, key is a string and val is of type number
    return cumulativeValue   val;
  },
  0 // the initial value
);

// totalPrice === 300
 

Я надеюсь, что это несколько объясняет, как возникают эти типы. Чтобы ответить на ваш вопрос, я думаю, что ваш редуктор немного испорчен, так как есть 2 функции. Чтобы исправить это, это должно сработать:

 .reduce(
  (cumulativeValue, [key, val]) => {
    const ret =
      cumulativeValue  
      (val.quantity ?? startPaymentIn?.invoiceItems[key] ?? 0) *
        parseInt(val.unitPrice);
    return ret;
  },
  0
);
 

Ответ №3:

Наконец я понял, что вместо reduce этого мне нужен простой цикл for.