如何在打字稿中声明成功/失败返回类型

Posted

技术标签:

【中文标题】如何在打字稿中声明成功/失败返回类型【英文标题】:How to declare success/fail return types in typescript 【发布时间】:2019-08-20 12:20:28 【问题描述】:

我有一个包,它简单地执行 HTTP 调用并返回成功响应或错误响应。我正在努力做到这一点,以便您在成功和错误时都能获得 IntelliSense。

这就是我所拥有的:

class ResultSuccess 
  userId: number;
  id: number;
  title: string;


class ResultError 
  error: boolean;


export function magic(): Promise<ResultSuccess> 
  return new Promise((resolve, reject) => 
      fetch('https://jsonplaceholder.typicode.com/todos/1')
        .then(response => response.json())
        .then(json => resolve(plainToClass(ResultSuccess, json as ResultSuccess)))
        .catch(err => 
            reject(plainToClass(ResultError,  error: true  as ResultError));
        );
);

这行得通,我对结果有了智能感知,但如果我将返回的主题设置为类似:

function magic(): Promise<ResultSuccess | ResultError>

我不再对成功或失败的结果进行智能感知。

我是打字稿的新手,有人可以建议一种方法来处理这个问题吗?或者有人可以看到问题吗?

【问题讨论】:

I no longer get intelisense on the success or fail outcomes. 怎么样?顺便说一句拒绝无法输入:github.com/Microsoft/TypeScript/issues/… 我得到函数将返回 ResultSuccess 的提示 | ResultError 但我没有自动完成属性名称(outcome.userIs 或 output.error)。那么这是处理https调用的正确方法吗? (输入成功的结果,如果不成功,让他们找出错误?)。 【参考方案1】:

解决方案 #1:抛出错误

我是打字稿新手

在这种情况下,我允许自己使用 asyncawait 重写您的 magic 函数,因为这是 2019 年的工作方式:

export async function magic(): Promise<ResultSuccess> 
  try 
    const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
    const json = await response.json();
    return plainToClass(ResultSuccess, json as ResultSuccess);
   catch (err) 
    throw plainToClass(ResultError,  error: true );
  

返回值是ResultSuccess 的承诺。该函数从不返回ResultError,但它可以抛出它。使用示例:

async function useMagic() 
  try 
    const result = await magic();
    // 'result' is of type 'ResultSuccess'
   catch (err) 
    // 'err' is of type 'any' and you know it is a 'ResultError'
  

解决方案#2:错误不抛出而是返回

如果您决定必须将错误作为结果值返回,您可以这样做:

export async function magic2(): Promise<ResultSuccess | ResultError> 
  try 
    // … same code as previously …
   catch (err) 
    return plainToClass(ResultError,  error: true );
  

然后,当您使用结果值时,您必须确定这是错误还是成功。这是一个解决方案:

写一个type guard:

function isResultError(result: ResultSuccess | ResultError): result is ResultError 
  return result["error"] !== undefined;

然后,使用它:

async function useMagic2() 
  const result = await magic2();
  if (isResultError(result)) 
    // Here, 'result' is of type 'ResultError'
   else 
    // Here, 'result' is of type 'ResultSuccess'
  

【讨论】:

解决方案 1 有意义,感谢您提供所有详细信息。如果错误是 ResultError 的一个实例,那么返回错误类并检查 catch 是否是一个好习惯? er => er instanceof myPackage.ResultError ? console.log("yap") : console.log("nope") @johnnyshrewd 使用上面的代码,不需要检查错误的类型,因为magic 的整个代码都被try / catch 包围。它不能扔别的东西。如果你想要自动完成,你可以直接投射:(err as ResultError).error 解决方案 #1 与 #2 的优缺点是什么?似乎我正在使用解决方案 #2 阅读越来越多的 TS 代码,至少在低级别。我正在尝试决定我应该关注哪种方法,以及为什么。谢谢。

以上是关于如何在打字稿中声明成功/失败返回类型的主要内容,如果未能解决你的问题,请参考以下文章

如何在打字稿中避免这种符号“| undefined”?

如何在打字稿中声明全局变量

如何在打字稿中正确导入自定义类型

如何在打字稿中对模型接口进行单元测试?

从订阅打字稿中返回值

如何创建一个从打字稿中的类中提取所有方法的类型?