【问题标题】:Returning a promise in an async function in TypeScript在 TypeScript 的异步函数中返回一个 Promise
【发布时间】:2023-03-13 16:35:02
【问题描述】:

据我了解,这两个函数在 JavaScript 中将具有相同的行为:

const whatever1 = (): Promise<number> => {
    return new Promise((resolve) => {
        resolve(4);
    });
};

const whatever2 = async (): Promise<number> => {
    return new Promise((resolve) => {
        resolve(4);
    });
};

但 TypeScript 似乎不喜欢第二个,它说:

Type '{}' is not assignable to type 'number'.

这是 TypeScript 中的错误,还是我对异步函数有误解?

【问题讨论】:

  • 请注意,在您的第二个函数中使用async 有点没用,因为该函数将立即返回一个 Promise 并且不会阻塞执行。
  • 离题,但如果你真的不关心承诺回报,你可以使用Promise&lt;any&gt;

标签: typescript


【解决方案1】:

这很复杂。

首先,在这段代码中

const p = new Promise((resolve) => {
    resolve(4);
});

p 的类型被推断为Promise&lt;{}&gt;。 typescript github上有open issue关于这个,所以可以说这是一个错误,因为显然(对于人类),p应该是Promise&lt;number&gt;

那么,Promise&lt;{}&gt;Promise&lt;number&gt; 兼容,因为基本上一个promise 的唯一属性是then 方法,而then 在这两种promise 类型中是兼容typescript rules for function types compatibility 的。这就是whatever1没有错误的原因。

但是async 的目的是假装你在处理实际值,而不是承诺,然后你在whatever2 中得到错误,因为{} 显然与number 不兼容。

所以async 的行为是相同的,但目前需要一些解决方法来使 typescript 编译它。在创建这样的 Promise 时,您可以简单地提供显式的泛型参数:

const whatever2 = async (): Promise<number> => {
    return new Promise<number>((resolve) => {
        resolve(4);
    });
};

【讨论】:

  • 感谢您的精彩解释...它有效
【解决方案2】:

当您执行new Promise((resolve)... 时,推断的类型是Promise&lt;{}&gt;,因为您应该使用new Promise&lt;number&gt;((resolve)

有趣的是,这个问题仅在添加 async 关键字时才突出显示。我建议将此问题报告给 TS 团队on GitHub

您可以通过多种方式解决此问题。以下所有函数具有相同的行为:

const whatever1 = () => {
    return new Promise<number>((resolve) => {
        resolve(4);
    });
};

const whatever2 = async () => {
    return new Promise<number>((resolve) => {
        resolve(4);
    });
};

const whatever3 = async () => {
    return await new Promise<number>((resolve) => {
        resolve(4);
    });
};

const whatever4 = async () => {
    return Promise.resolve(4);
};

const whatever5 = async () => {
    return await Promise.resolve(4);
};

const whatever6 = async () => Promise.resolve(4);

const whatever7 = async () => await Promise.resolve(4);

在您的 IDE 中,您将能够看到所有这些函数的推断类型是 () =&gt; Promise&lt;number&gt;

【讨论】:

  • 如果 Promise 函数中的某处有拒绝,返回类型如何仍然相同?
猜你喜欢
  • 2021-10-18
  • 1970-01-01
  • 1970-01-01
  • 2020-07-09
  • 2018-04-08
  • 2020-07-09
  • 2017-10-16
  • 1970-01-01
  • 2018-04-13
相关资源
最近更新 更多