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