【问题标题】:Typed Promise changes return type to unknown when `finally` is added当添加“finally”时,Typed Promise 将返回类型更改为未知
【发布时间】:2021-02-25 12:54:11
【问题描述】:

我有一个静态类型返回类型的常规承诺:

export const hasActiveSubscription = (whatEver: string): Promise<string> => 
  new Promise((resolve, reject) => {
    if (true){
      resolve('imastring')
    }
    reject(new Error('nope'))
  })

到目前为止一切顺利,但如果我添加 finally 块,它会将返回类型更改为 unknown 并且无法传递该字符串类型,例如

export const hasActiveSubscription = (whatEver: string): Promise<string> => 
  new Promise((resolve, reject) => {
    if (true){
      resolve('imastring')
    }
    reject(new Error('nope'))
  }).finally(console.info)

类型“Promise”不可分配给类型“Promise”。
类型“未知”不能分配给类型“字符串”。

如何在保留 finally 块的同时保留原始返回类型?

如果有帮助,我的实际代码有一个 setTimeout(以确保此函数不会花费太长时间返回),我想在 finally 上清除超时,而不是在 5 个不同位置清除超时。

【问题讨论】:

    标签: typescript es6-promise


    【解决方案1】:

    如果从函数签名的返回位置去掉类型注解,你会注意到实际的返回类型是Promise&lt;unknown&gt;,而不是你预期的Promise&lt;string&gt;,这构成了错误的第一部分:

    const hasActiveSubscription: (whatEver: string) => Promise<unknown>;
    

    Promise是一个泛型接口,其finally方法在其返回类型注解中使用了接口的类型参数(示例来自ES2018 lib):

    interface Promise<T> {
        finally(onfinally?: (() => void) | undefined | null): Promise<T>
    }
    

    你需要做的就是指定构造的Promise的类型,一切都会好的:

    export const hasActiveSubscription = (whatEver: string) => 
      new Promise<string>((resolve, reject) => {
        if (true){
          resolve('imastring')
        }
        reject(new Error('nope'))
      }).finally(console.info) //no error, Promise<string> is inferred
    

    Playground


    小记 - 您的示例在 reject 调用中有一个不匹配的括号

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 1970-01-01
      • 2019-07-25
      • 1970-01-01
      • 2016-10-28
      相关资源
      最近更新 更多