【问题标题】:Typescript Promise chaining - changing the returned typeTypescript Promise 链接 - 更改返回的类型
【发布时间】:2022-01-26 22:18:33
【问题描述】:

我有两个要调用的异步 get,第二个使用第一个的输出,它们返回的类型(在 Promise 中)是不同的。

这些来自 React 中的 AsyncStorage 库。

我的代码是:

    function fetchAllSecretsRaw(): Promise<[string, string | null][]> {
        return AsyncStorage.getAllKeys().then((allKeys) => {
            return AsyncStorage.multiGet(allKeys.filter(isSecretKey));
        });
    }

我很惊讶在查看 Promise 声明时这种类型检查。这是如何运作的? Promise&lt;[string, string | null][]&gt;如何满足Promise&lt;string[]&gt;(来自TResult1 = T

异步函数签名是:

getAllKeys(callback?: (error?: Error, keys?: string[]) => void): Promise<string[]>;

  multiGet(
    keys: string[],
    callback?: (errors?: Error[], result?: [string, string | null][]) => void
  ): Promise<[string, string | null][]>;

而 .then 在Promise&lt;T&gt; 上是:

    then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
        onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;

第一个getAllKeys() 给了我一个Promise&lt;string[]&gt;,根据Promise 声明,这意味着T=string[]

既然TResult1 = T(从那时的声明then&lt;TResult1 = T,)这是否意味着TResult1 = string[]

但我传递的onfulfilled 函数实际上返回一个Promise&lt;[string, string | null][]&gt;,即一个元组数组而不是字符串数组。

【问题讨论】:

    标签: typescript promise typescript-generics


    【解决方案1】:

    TResult1onfulfilled 函数的返回值类型(在您的情况下为[string, string | null][]),或者如果onfulfilled 不存在,则为T 的类型(在您的情况下为string[])。

    由于您的 onfulfilled 函数是:

    (allKeys) => {
      return AsyncStorage.multiGet(allKeys.filter(isSecretKey));
    }
    

    返回一个Promise&lt;[string, string | null][]&gt;。因此,此类型检查良好。这不是一个错误。

    【讨论】:

    • 但是.then 声明也限制了TResult1 = T。所以我们有两个冲突的 TResult1,Promise&lt;[string, string | null][]&gt;Promise&lt;T&gt;,其中 T 是 string[]
    • 啊,我知道混乱来自哪里了!我应该读得更好一点,但回答得有点匆忙。 TResult1 不限于 T。其默认值设置为T。这意味着当onfulfilled 不存在并且TResult1 未知时,TResult1 的类型值将是T,因此then 的返回值将是Promise&lt;T&gt;
    • 更新了我的答案
    【解决方案2】:

    .then 声明还限制了 TResult1 = T

    不,它不会限制它(就像 extends 子句那样) - 这只是没有提供 onfulfilled 回调时的默认值。

    但是你确实提供了一个,它的类型是(value: string[]) =&gt; Promise&lt;[string, string | null][]&gt;,所以TResult1被正确地推断为[string, string | null][]

    【讨论】:

    猜你喜欢
    • 2021-10-17
    • 2018-09-08
    • 2020-09-19
    • 2016-01-02
    • 1970-01-01
    • 2018-01-07
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多