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

dum*_*ter 32 typescript

我的理解是这两个函数在JavaScript中具有相同的行为:

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

const whatever2 = async (): Promise<number> => {
    return new Promise((resolve) => {
        resolve(4);
    });
};
Run Code Online (Sandbox Code Playgroud)

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

Type '{}' is not assignable to type 'number'.
Run Code Online (Sandbox Code Playgroud)

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

art*_*tem 53

情况很复杂.

首先,在这段代码中

const p = new Promise((resolve) => {
    resolve(4);
});
Run Code Online (Sandbox Code Playgroud)

p推断的类型Promise<{}>.在打字稿github上存在关于这个的公开问题,所以可以说这是一个错误,因为显然(对于人类而言)p应该是Promise<number>.

然后,Promise<{}>兼容Promise<number>,因为promise基本上唯一的属性是then方法,并且then根据函数类型兼容性的typescript规则在这两种promise类型中兼容.这就是为什么没有错误的原因whatever1.

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

所以async行为是一样的,但目前有一些解决方法是使得打字稿编译它.在创建这样的promise时,您可以简单地提供显式泛型参数:

const whatever2 = async (): Promise<number> => {
    return new Promise<number>((resolve) => {
        resolve(4);
    });
};
Run Code Online (Sandbox Code Playgroud)


Rem*_*sen 15

当你这样做时new Promise((resolve)...,推断类型是Promise<{}>因为你应该使用new Promise<number>((resolve).

有趣的是,只有在async添加关键字时才会突出显示此问题.我建议在GitHub上向TS团队报告此问题.

有很多方法可以解决这个问题.以下所有函数都具有相同的行为:

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);
Run Code Online (Sandbox Code Playgroud)

在IDE中,您将能够看到所有这些函数的推断类型() => Promise<number>.