【问题标题】:Typescript error I don't understand in my promise wrapper我的承诺包装器中我不理解的打字稿错误
【发布时间】:2021-08-07 02:09:11
【问题描述】:

为什么我不能通过链接 then & catch 来返回承诺,我看不出这里有什么区别。

type SuccessResponse<T> = [T, null]

type ErrorResponse<U> = [null, U]

type Result<T, U> = Promise<SuccessResponse<T> | ErrorResponse<U>>

export const promiseWrapper = async <T, U extends Error>(
  promise: Promise<T>
): Result<T, U> => {

  // --- This works ---
  try {
    const data = await promise
    return Promise.resolve([data, null])
  } catch (error) {
    return Promise.resolve([null, error])
  }
  // ---


  // --- Doing this instead cause TypeScript error ---

  // return promise
  //   .then((data) => [data, null])
  //   .catch((error) => Promise.resolve([null, error]))
  // ---

}

这是我得到的错误。我把它读作我返回的承诺,在某种程度上不考虑“then & catch”链。通过 async/await (工作方式)和解耦承诺,编译器明白我想要返回 Result 承诺?

如果我想使用 Promise 链,我如何告诉 typescript 我的 Promise 将返回 Result?

Type '(T | null)[] | [null, any]' is not assignable to type 'SuccessResponse<T> | ErrorResponse<U>'.
  Type '(T | null)[]' is not assignable to type 'SuccessResponse<T> | ErrorResponse<U>'.
    Type '(T | null)[]' is not assignable to type 'ErrorResponse<U>'.
      Target requires 2 element(s) but source may have fewer.

【问题讨论】:

  • 有点旁注,但您的结果似乎很奇怪。您似乎采用了成功/错误回调样式并将其作为元组结果放入承诺中。而我希望错误是拒绝承诺。如果你真的想要两者,似乎你在追求Either,这确实更有意义,但我不确定承诺中的元组是实现它的最佳方式。

标签: typescript promise compiler-errors


【解决方案1】:

问题是 Typescript 无法区分 [T, null] 和 (T|null)[]。 [data, null] 的值在这两种情况下都是正确的。

要解决此问题,您似乎需要指定 .then 返回的类型:

  return promise
    .then<SuccessResponse<T>>((data) => [data, null])
    .catch((error) => [null, error]);

【讨论】:

  • 它有效,但为什么我必须这样做,而且只针对 SucessResponse? ```(T|null)[]´´´ 来自哪里?
  • Typescript 尝试推断 [data, null] 的含义并以 (T|null)[] 结束。此类型是一个元素数组,可以为 T 或 null。当比较 (T|null)[] 和你的类型 [T, null] 时,它不会匹配。
  • 我现在才发现还有另一种解决方案可以帮助Typescript推断元组类型:typescriptlang.org/docs/handbook/release-notes/…基本上,你需要将你的类型设置为只读type SuccessResponse&lt;T&gt; = readonly [T, null];和type ErrorResponse&lt;U&gt; = readonly [null, U];,然后你可以做.then((data) =&gt; [data, null] as const) 和.catch((error) =&gt; [null, error] as const)。
猜你喜欢
  • 2021-08-21
  • 2017-03-15
  • 2017-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 2019-10-15
  • 1970-01-01
相关资源
最近更新 更多