正确的元组返回类型,以避免非null / undefined运算符?

时间:2019-05-09 08:45:49

标签: typescript

我有一个函数,可以保证返回一个元组的已解决结果并捕获错误:

function resultOf<T>(promise: Promise<T>): Promise<[null, T] | [any]> {
  return promise
    .then((data: T): [null, T] => [null, data])
    .catch((err: any) => [err])
  ;
}

现在,当我调用该函数并检查元组是否包含错误时,如果没有错误,我希望不要求使用非null断言运算符:

  // ...
  const [error, result] = await resultOf(foo());
  if(error) {
    // handle error
    return Promise.reject(error);
  }
  const bar = result.bar; // <- Object is possibly 'undefined'
  const bar = result!.bar; // <- This is what I'd like to avoid
  // ...

这是我的两个问题: *为什么不起作用? *如何纠正类型,例如避免不必添加非null断言运算符?

谢谢!

2 个答案:

答案 0 :(得分:1)

Typescript不会跟随这些“纠缠”的变量来查看它们如何相互影响。您可以使用元组本身,并根据长度来区分元组并集,然后在以下情况下对其进行破坏:

function resultOf<T>(promise: Promise<T>): Promise<[null, T] | [any]> {
  return promise
    .then((data: T): [null, T] => [null, data])
    .catch((err: any) => [err])
  ;
}

async function x() {
  const r = await resultOf(Promise.resolve({ bar: 1 }));
  if (r.length == 1) {
    // handle error
    return Promise.reject(r[0]);
  }
  var [_, result] = r;
  const bar = result.bar; // <- Ok now
}

答案 1 :(得分:0)

errorresult似乎彼此独立。而且因为这样的打字稿无法知道您的函数将返回一个或另一个不为null或未定义。元组的类型推断没有那么深入。

我想我会把第一个写成

if (!result) {
  //...
}

将在if result之后定义,并且肯定不能为null。并且error在Promise中仍然是任何类型。