在TypeScript中返回异步函数中的promise

时间:2017-05-09 23:11:00

标签: typescript

我的理解是这两个函数在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中的错误,还是我误解了异步函数?

2 个答案:

答案 0 :(得分:38)

这很复杂。

首先,在此代码中

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

p的类型推断为Promise<{}>。关于typescript github有open issue,所以可以说这是一个bug,因为很明显(对于一个人来说),p应该是Promise<number>

然后,Promise<{}>Promise<number>兼容,因为承诺基本上唯一的属性是then方法,而then在这两种承诺类型中是兼容的与typescript rules for function types compatibility。这就是whatever1中没有错误的原因。

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

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

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

答案 1 :(得分:11)

执行new Promise((resolve)...后,推断的类型为Promise<{}>,因为您应该使用new Promise<number>((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中,您将能够看到所有这些函数的推断类型为() => Promise<number>