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

推荐答案

这很复杂.

首先,在这段代码中

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

p的类型推断为Promise<{}>.在typescript github上有open issue个,所以可以说这是一个bug,因为显然(对于人类而言),p应该是Promise<number>.

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

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

所以async的行为是相同的,但目前需要一些变通方法来让typescript编译它.在创建这样的promise 时,您可以简单地提供明确的泛型参数:

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

Typescript相关问答推荐

为什么当类类型与方法参数类型不兼容时,该函数可以接受类类型

端点之间的TEK查询缓存

类型缩小对(几乎)受歧视的unions 不起作用

类型断言添加到类型而不是替换

如何在Reaction路由v6.4加载器和操作中获得Auth0访问令牌?

如何消除在Next.js中使用Reaction上下文的延迟?

使用Redux Saga操作通道对操作进行排序不起作用

如何 bootstrap TS编译器为类型化属性`T`推断正确的类型?

为什么我的动画状态在组件实例之间共享?

如何将spread operator与typescripts实用程序类型`参数`一起使用

TypeScrip:如何缩小具有联合类型属性的对象

如何在具有嵌套数组的接口中允许新属性

基于区分的联合键的回调参数缩小

如何在TypeScript中描述和实现包含特定属性的函数?

T的typeof键的Typescript定义

记录的子类型<;字符串,X>;没有索引签名

React-跨组件共享功能的最佳实践

确保财产存在

如何限定索引值必须与相应属性的id字段相同

传入类型参数<;T>;变容函数