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

时间:2019-03-29 14:20:31

标签: javascript node.js typescript typescript-generics

我有一个仅执行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>

我不再对成功或失败的结果有深刻的认识。

我是打字机的新手,有人可以建议一种解决方法,还是有人可以看到问题?

1 个答案:

答案 0 :(得分:1)

解决方案1:引发错误

  

我是打字稿新手

在这种情况下,我允许自己使用magicasync重写await函数,因为这是在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'
  }
}