Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Typescript(Type';undefined';不可分配给Type)为什么我的数组有一个| undefined?_Javascript_Arrays_Typescript - Fatal编程技术网

Javascript Typescript(Type';undefined';不可分配给Type)为什么我的数组有一个| undefined?

Javascript Typescript(Type';undefined';不可分配给Type)为什么我的数组有一个| undefined?,javascript,arrays,typescript,Javascript,Arrays,Typescript,我有一个名为combinedMarkets的数组,它是5个或3个不同市场数组的组合。所有这些阵列都具有以下接口imarketaset[]: export interface IMarketAsset { exchange: string; base: string; quote: string; price_quote: string; timestamp: string; } 以下是发生typescript错误的地方: const combinedMarkets = as

我有一个名为
combinedMarkets
的数组,它是5个或3个不同市场数组的组合。所有这些阵列都具有以下接口
imarketaset[]

export interface IMarketAsset {
  exchange: string;
  base: string;
  quote: string;
  price_quote: string;
  timestamp: string;
}
以下是发生typescript错误的地方:

const combinedMarkets = asset !== 'BTC' && asset !== 'ETH' ?
  btcMarkets.concat(ethMarkets).concat(marketUSD).concat(marketUSDC).concat(marketUSDT) :
  marketUSD.concat(marketUSDC).concat(marketUSDT);

const filteredMarkets = combinedMarkets.length > 0 ? filterByUSDbase(asset, combinedMarkets) : [];
“({price_quote:string;exchange:string;base:string;quote:string;timestamp:string;}未定义)[]”类型的参数不能分配给“imarketaset[]”类型的参数。 类型“{price_quote:string;exchange:string;base:string;quote:string;timestamp:string;}未定义”不能分配给类型“imarketaset”。 类型“undefined”不可分配给类型“IMarketAsset”。ts(2345)

为什么组合市场是
imarketaset类型的对象的数组
或未定义的对象的数组?

全组合交换数据函数 Util函数 下面是我在主函数中使用的另外两个util函数。此外,我还将问题缩小到
btcMarkets
ethMarkets
阵列。所以看看
filterByExchangeBase

import * as R from 'ramda'

import { USD_CURRENCIES } from '../shared/constants/api'
import { IMarketAsset } from '../shared/types'

const calculateBasePrice = (assetBtcPrice: string | number, btcPrice: string | number) => 
  (Number(assetBtcPrice) * Number(btcPrice)).toString();

export const filterByExchangeBase =
  (exchanges: IMarketAsset[], usdtExchanges: IMarketAsset[], usdExchanges: IMarketAsset[]) =>
    exchanges.map((exchange) => {
      let basePriced = usdtExchanges.filter((btcExchange) => btcExchange.exchange === exchange.exchange)[0];

      if (!basePriced) {
        basePriced = usdExchanges.filter((btcExchange) => btcExchange.exchange === exchange.exchange)[0];
      }

      if (basePriced) {
        const { price_quote: assetBtcPrice } = exchange;
        const { price_quote: btcPrice } = basePriced;

        return {
          ...exchange,
          price_quote: calculateBasePrice(assetBtcPrice, btcPrice)
        }
      }
    });

export const filterByUSDbase = (asset: string, combinedMarkets: IMarketAsset[] | undefined) => {
  if (!combinedMarkets) return [];
  return R.not(R.any(R.equals(asset))(USD_CURRENCIES))
    ? combinedMarkets.filter((marketAsset: IMarketAsset) => {
      if (marketAsset && marketAsset.base) {
        return marketAsset.base === asset;
      }
    }) : [];
}
为什么combinedMarkets是一个数组,并且是类型为IMarketAsset或undefined的对象


因为任何
marketXXX
数组都是
imarketaset | undefined
的数组(而不仅仅是
imarketaset

尝试将类型定义为每个选项的数组,而不是组合它们:

const组合市场:{
价格:字符串;
交换:字符串;
基:字符串;
引号:字符串;
时间戳:字符串;
}[]|未定义[]=[];

问题在于,在我的
filterByExchangeBase
util函数中,我使用了
.map
而不是
.filter
,这将导致该数组中存在一些
未定义的
对象。切换到filter可确保只有现有项才能进入数组

更新:通过将.map更改为.filter,报价更新不会生效 重构逻辑,以确保btcMarkets和ethMarkets在为空时不会被使用

export const combineExchangeData =
  (asset: string, { marketBTC, marketETH, marketUSD, marketUSDT, marketUSDC }: IGetMarketsRes) => {
    const btcBasedExchanges = marketBTC.filter((market: IMarketAsset) => market.base === asset);
    const ethBasedExchanges = marketETH.filter((market: IMarketAsset) => market.base === asset);
    const btcUSDTprices = marketUSDT.filter((market: IMarketAsset) => market.base === 'BTC');
    const btcUSDprices = marketUSD.filter((market: IMarketAsset) => market.base === 'BTC');
    const ethUSDTprices = marketUSDT.filter((market: IMarketAsset) => market.base === 'ETH');
    const ethUSDprices = marketUSD.filter((market: IMarketAsset) => market.base === 'ETH');

    const btcPricedMarkets = notBTCorETH(asset) ? filterCryptoBase(btcBasedExchanges, btcUSDTprices, btcUSDprices) : [];
    const ethPricedMarkets = notBTCorETH(asset) ? filterCryptoBase(ethBasedExchanges, ethUSDTprices, ethUSDprices) : [];

    const btcMarkets = R.not(R.isEmpty(btcPricedMarkets)) ? btcPricedMarkets.filter((market: IMarketAsset) => R.not(R.isNil(market))) : [];
    const ethMarkets = R.not(R.isEmpty(ethPricedMarkets)) ? ethPricedMarkets.filter((market: IMarketAsset) => R.not(R.isNil(market))) : [];

    const combinedMarkets = notBTCorETH(asset) ?
      btcMarkets.concat(ethMarkets).concat(marketUSD).concat(marketUSDC).concat(marketUSDT) :
      marketUSD.concat(marketUSDC).concat(marketUSDT);

    const filteredMarkets = filterByUSDbase(asset, combinedMarkets);

    if (R.isEmpty(filteredMarkets)) return [];

    return filteredMarkets.map((market: IMarketAsset) => ({
      ...market,
      price_quote: formatPrice(market.price_quote)
    }));
  };


是的,我正在试图找出原因,我想我已经把它缩小到了
combinedMarkets
,在
concat
部分逻辑中有时包含空数组,所以我会尝试过滤空数组。好吧,我的解决方案并不能真正解决问题。我必须使用
export-const-filterCryptoBase=(exchanges:imarketaset[]|任何
都是为了避免键入脚本错误。明天将为赏金提供此功能。?但是每个数组都是相同类型的
imarketaset
,因此当我对所有数组进行浓缩时,它们仍然是
imarketaset
类型。你能发布一个
类型的示例吗
你是正确的,因为我需要一个同时支持
imarketaset>的类型
且未在数组中定义。
import * as R from 'ramda'

import { USD_CURRENCIES } from '../shared/constants/api'
import { IMarketAsset } from '../shared/types'

const calculateBasePrice = (assetBtcPrice: string | number, btcPrice: string | number) => 
  (Number(assetBtcPrice) * Number(btcPrice)).toString();

export const filterByExchangeBase =
  (exchanges: IMarketAsset[], usdtExchanges: IMarketAsset[], usdExchanges: IMarketAsset[]) =>
    exchanges.map((exchange) => {
      let basePriced = usdtExchanges.filter((btcExchange) => btcExchange.exchange === exchange.exchange)[0];

      if (!basePriced) {
        basePriced = usdExchanges.filter((btcExchange) => btcExchange.exchange === exchange.exchange)[0];
      }

      if (basePriced) {
        const { price_quote: assetBtcPrice } = exchange;
        const { price_quote: btcPrice } = basePriced;

        return {
          ...exchange,
          price_quote: calculateBasePrice(assetBtcPrice, btcPrice)
        }
      }
    });

export const filterByUSDbase = (asset: string, combinedMarkets: IMarketAsset[] | undefined) => {
  if (!combinedMarkets) return [];
  return R.not(R.any(R.equals(asset))(USD_CURRENCIES))
    ? combinedMarkets.filter((marketAsset: IMarketAsset) => {
      if (marketAsset && marketAsset.base) {
        return marketAsset.base === asset;
      }
    }) : [];
}
export const combineExchangeData =
  (asset: string, { marketBTC, marketETH, marketUSD, marketUSDT, marketUSDC }: IGetMarketsRes) => {
    const btcBasedExchanges = marketBTC.filter((market: IMarketAsset) => market.base === asset);
    const ethBasedExchanges = marketETH.filter((market: IMarketAsset) => market.base === asset);
    const btcUSDTprices = marketUSDT.filter((market: IMarketAsset) => market.base === 'BTC');
    const btcUSDprices = marketUSD.filter((market: IMarketAsset) => market.base === 'BTC');
    const ethUSDTprices = marketUSDT.filter((market: IMarketAsset) => market.base === 'ETH');
    const ethUSDprices = marketUSD.filter((market: IMarketAsset) => market.base === 'ETH');

    const btcPricedMarkets = notBTCorETH(asset) ? filterCryptoBase(btcBasedExchanges, btcUSDTprices, btcUSDprices) : [];
    const ethPricedMarkets = notBTCorETH(asset) ? filterCryptoBase(ethBasedExchanges, ethUSDTprices, ethUSDprices) : [];

    const btcMarkets = R.not(R.isEmpty(btcPricedMarkets)) ? btcPricedMarkets.filter((market: IMarketAsset) => R.not(R.isNil(market))) : [];
    const ethMarkets = R.not(R.isEmpty(ethPricedMarkets)) ? ethPricedMarkets.filter((market: IMarketAsset) => R.not(R.isNil(market))) : [];

    const combinedMarkets = notBTCorETH(asset) ?
      btcMarkets.concat(ethMarkets).concat(marketUSD).concat(marketUSDC).concat(marketUSDT) :
      marketUSD.concat(marketUSDC).concat(marketUSDT);

    const filteredMarkets = filterByUSDbase(asset, combinedMarkets);

    if (R.isEmpty(filteredMarkets)) return [];

    return filteredMarkets.map((market: IMarketAsset) => ({
      ...market,
      price_quote: formatPrice(market.price_quote)
    }));
  };
export const filterCryptoBase =
  (exchanges: IMarketAsset[] | any, usdtExchanges: IMarketAsset[], usdExchanges: IMarketAsset[]) => {
    return exchanges.map((exchange: IMarketAsset) => {
      let basePriced = usdtExchanges.filter((btcExchange) => btcExchange.exchange === exchange.exchange)[0];
      if (!basePriced) {
        basePriced = usdExchanges.filter((btcExchange) => btcExchange.exchange === exchange.exchange)[0];
      }

      if (exchange && basePriced && exchange.price_quote && basePriced.price_quote) {
        const { price_quote: assetBtcPrice } = exchange; // Asset price in BTC/ETH
        const { price_quote: usdPrice } = basePriced; // BTC/ETH price in USDT/USD
        const price_quote = calculateBasePrice(assetBtcPrice, usdPrice).toString();

        return {
          ...exchange,
          price_quote
        }
      }

      return null;
    });
  }