函数缺少结束的返回语句,返回类型不包括'undefined'。

38

函数缺少结束的返回语句且返回类型不包括 'undefined'。

在下面的 async/await 函数中,我原本的返回类型是 Promise: <any>,但我想要改正它,于是我做了以下操作:

export const getMarkets = async (): Promise<IGetMarketsRes> => {
  try {
    const nomicsUSD = prepHeaders('USD');
    const marketUSD = await nomicsUSD.get(exchangeMarketPrices);
    const nomicsUSDC = prepHeaders('USDC');
    const marketUSDC = await nomicsUSDC.get(exchangeMarketPrices);
    const nomicsUSDT = prepHeaders('USDT');
    const marketUSDT = await nomicsUSDT.get(exchangeMarketPrices);

    console.log('marketUSD', marketUSD);

    return {
      marketUSD: marketUSD.data,
      marketUSDC: marketUSDC.data,
      marketUSDT: marketUSDT.data
    }
  } catch (err) {
    console.error(err);
  }
}

然而,这会导致上述错误。

在此输入图片描述

调用getMarkets的位置:

export const fetchMarketPrices = (asset: string) => (dispatch: any) => {
  dispatch(actionGetMarketPrices);
  return getMarkets().then((res) => {
    const { marketUSD, marketUSDC, marketUSDT } = res;
    const combinedExchanges = marketUSD.concat(marketUSDC).concat(marketUSDT);
    const exchangesForAsset = combinedExchanges.filter((marketAsset: IMarketAsset) =>
      marketAsset.base === asset);
    return dispatch(actionSetMarketPrices(exchangesForAsset));
  });
}

什么是适当的类型,用于 Promise<> 语法?


我也尝试了这个,本来以为这是正确的方法,但是发现 Promise 缺少返回值。不过这是一个异步等待函数,在 try 语句中才有返回值:

export const getMarkets = async (): Promise<IGetMarketsRes> => {

enter image description here


2
因此,在出现错误的情况下,函数将隐式返回“undefined”。这会对调用者产生什么影响?难道不是在“console.log”之后重新抛出错误更好吗?这样也可以将“return”移动到“try {} catch {}”之外,以便TS可以正常工作。 - skyboyer
@skyboyer 哦,是的,这个函数没有 try catch 也能正常工作,感谢你的提示!如果你想发帖,请继续。否则我会继续重构然后发布我的修复方案 :) - Leon Gaban
1
或者你可以声明一个返回类型为 Promise<IGetMarketsRes | undefined>,但看起来更像是你不想在那个函数中处理错误。 - Bergi
@Bergi 您的解决方案使我能够保留 try catch,您想要发布答案吗? - Leon Gaban
@LeonGaban 在你使用 IGetMarketsRes 的调用处,没有加上 try/catch 吗? - Bergi
显示剩余2条评论
4个回答

35

最好的解决方案是在捕获时抛出错误,而不是取消定义返回类型。使用 undefined 类型会否则完全失去使用 TypeScript 的意义。

试试这个:

export const getMarkets = async (): Promise<IGetMarketsRes> => {
  try {
     // Your code :)
  } catch (err) {
    // Throw error
    throw(err)
  }
}

15

保持try catch的解决方案

export const getMarkets = async (): Promise<IGetMarketsRes | undefined> => {
  try {
    const nomicsUSD = prepHeaders('111');
    const marketUSD = await nomicsUSD.get(exchangeMarketPrices);
    const nomicsUSDC = prepHeaders('222');
    const marketUSDC = await nomicsUSDC.get(exchangeMarketPrices);
    const nomicsUSDT = prepHeaders('333');
    const marketUSDT = await nomicsUSDT.get(exchangeMarketPrices);

    const { data: dataUSD } = marketUSD;
    const { data: dataUSDC } = marketUSDC;
    const { data: dataUSDT } = marketUSDT;

    if (R.isEmpty(dataUSD) || R.isEmpty(dataUSDC) || R.isEmpty(dataUSDT)) {
      console.error('Market data unavailable');
    }

    return {
      marketUSD: marketUSD.data,
      marketUSDC: marketUSDC.data,
      marketUSDT: marketUSDT.data
    }
  } catch (error) {
    console.error(error);
  }
}

一个更好的DRY示例

https://codereview.stackexchange.com/questions/213909/get-an-array-of-currency-exchange-prices-based-on-asset

export const fetchMarket = async (currency: string): Promise<any> => {
  try {
    const request = prepHeaders(currency);
    const response =  await request.get(EXCHANGE_MARKET_PRICES);
    if (!response) {
      throw new Error('USD Markets unavailable.');
    }
    return response.data;
  }
  catch(err) {
    console.error(err);
  }
}

// GET Market prices
// http://docs.nomics.com/#operation/getMarkets
export const getMarkets = async (): Promise<IGetMarketsRes | undefined> => {
  try {
    const markets: IMarketRes = {};

    for (let currency of BASE_CURRENCIES) {
      const key = 'market' + currency;
      markets[key] = await fetchMarket(currency);
    }

    return {
      marketUSD: markets['marketUSD'],
      marketUSDC: markets['marketUSDC'],
      marketUSDT: markets['marketUSDT'],
    }
  } catch (error) {
    console.error(error);
  }
}

并且在动作文件中调用:

// Fetch USD, USDC & USDT markets to filter out Exchange List.
export const fetchMarketPrices = (asset: string) => (dispatch: any) => {
  dispatch(actionGetMarketPrices);
  return getMarkets().then((res) => {
    if (res) {
      const exchangesForAsset = combineExchangeData(asset, res);
      return dispatch(actionSetMarketPrices(exchangesForAsset));
    }
  });
}

1
为什么重新抛出错误不是被接受的答案?如果你使用了undefined类型,在某些情况下会得到TS7030:Not all code paths return a value - Cristian Flórez

7

如果出现错误,你的代码会隐式返回undefined,因为你捕获了error但没有将其重新抛出。

我猜你的tsconfig.json文件中设置了noImplicitReturnstrue。如果将其改为false,编译器错误将不再显示。然而,我建议仍将noImplicitReturns设置为true,并在catch子句中重新抛出错误。

如果符合应用程序逻辑,您也可以在catch块中返回默认的IGetMarketsRes。我制作了一个视频,展示了处理error TS2366的不同可能性:https://www.youtube.com/watch?v=8N_P-l5Kukk&t=363s


-1

你需要在catch中抛出错误,这样可以解决问题。像这样

catch (error) {
    console.log(error);
    throw new Error("Something is Wrong!")
}

这只是重复了Nojze的答案 - trincot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接