我有一个名为combinedMarkets
的数组,它是5个或3个不同市场数组的组合。所有这些数组都具有以下接口IMarketAsset[]
:
export interface IMarketAsset {
exchange: string;
base: string;
quote: string;
price_quote: string;
timestamp: string;
}
出现打字稿错误的地方:
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;} | undefined)[]'类型的参数不能分配给'IMarketAsset []'类型的参数。 输入'{price_quote:string;交换:字符串; base:字符串; quote:字符串;时间戳:字符串; } |未定义”不能分配给“ IMarketAsset”类型。 类型“未定义”不能分配给类型“ IMarketAsset”。ts(2345)
const combinedMarkets: ({ price_quote: string; exchange: string; base: string; quote: string; timestamp: string; } | undefined)[]
为什么CombinedMarkets是IMarketAsset
类型或未定义对象的数组?
// Filter by BTC, ETH, USD, USDT or USDC prices
// If asset has BTC/ETH pairing, obtain exchange BTC/ETH price to calculate assets USD/USDT value
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 = filterByExchangeBase(btcBasedExchanges, btcUSDTprices, btcUSDprices);
const ethPricedMarkets = filterByExchangeBase(ethBasedExchanges, ethUSDTprices, ethUSDprices);
const btcMarkets = btcPricedMarkets.filter((market) => R.not(R.isNil(market)));
const ethMarkets = ethPricedMarkets.filter((market) => R.not(R.isNil(market)));
const combinedMarkets = asset !== 'BTC' && asset !== 'ETH' ?
btcMarkets.concat(ethMarkets).concat(marketUSD).concat(marketUSDC).concat(marketUSDT) :
marketUSD.concat(marketUSDC).concat(marketUSDT);
console.log('combinedMarkets', combinedMarkets);
const filteredMarkets = combinedMarkets.length > 0 ? filterByUSDbase(asset, combinedMarkets) : [];
console.log('filteredMarkets', filteredMarkets);
if (R.isEmpty(filteredMarkets)) return [];
return filteredMarkets.map((market: IMarketAsset) => {
if (market) {
return {
...market,
price_quote: formatPrice(market.price_quote)
}
}
});
};
这是我在主函数中使用的另外两个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;
}
}) : [];
}
答案 0 :(得分:1)
为什么CombinedMarkets是一个数组,且对象类型为IMarketAsset或未定义
因为任何marketXXX
数组,所以是IMarketAsset | undefined
的数组(而不只是IMarketAsset
。
答案 1 :(得分:0)
尝试将类型定义为每个选项的数组,而不是将它们组合在一起:
__new__
答案 2 :(得分:0)
问题在于,在我的filterByExchangeBase
实用函数中,我使用.map
而不是.filter
,这将导致该数组中的某些undefined
对象。切换到过滤器可确保只有现有项目才能将其放入数组。
...
重构逻辑以确保如果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)
}));
};
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;
});
}