繁体   English   中英

TypeScript:Promise.all 不处理联合类型

[英]TypeScript: Promise.all doesn't handle union types

我有以下一段代码导致 TypeScript 编译错误:

type Promisable = (() => Promise<string>) | (() => Promise<number>);

const func = async (promisable: Promisable) => {
  await Promise.all([promisable()]);
};

错误如下

没有重载匹配这个调用。 最后一次重载给出了以下错误。 '(Promise | Promise)[]' 类型的参数不可分配给 'Iterable>' 类型的参数。 'Symbol.iterator.next(...)' 返回的类型在这些类型之间不兼容。

作为记录,删除联合类型按预期工作:

type Promisable = () => Promise<string>;

const func = async (promisable: Promisable) => {
  await Promise.all([promisable()]);
};

你可以在这里看到的错误自己https://www.typescriptlang.org/play/?ssl=4&ssc=3&pln=1&pc=1#code/C4TwDgpgBACgTgewLYEsDOBDARgG2gXigAoiBKKfAPlkVTQgB41g4UA7Ac0vIB9iyK1eMnSM2AVyRYIcbgG4AsACgAxgjbMoAM3FsVFKBjQg9xMLXTY8ALhojMuCOSpQA3sqiGA7hhTA7dBAAdBg4OEQA2ub2VhBkALqkikoAvnJAA

是否不能将联合类型与Promise.all结合使用?

编辑:我知道可以使用() => Promise<string|number> 但是在一个异步函数很多、类型很大的高级应用中,把函数的联合转换成联合的函数并不容易。 从代码的角度来看,它也不是很实用。

更新

这是使用当前promise 类型声明进行类型推断失败的情况之一。 最简单的解决方案是手动添加泛型类型参数:

const promisable: Promisable = ...
const res = await Promise.all<string | number>([promisable()]); 
// res: (string|number)[]

您可能会推断string | number 自动string | number

type PromiseReturn<T> = T extends () => Promise<infer I> ? I : never
const res = await Promise.all<PromiseReturn<Promisable>>([promisable()]);

使用TypeScript 4.1 :更复杂的、潜在嵌套的 Promise 类型可以使用自定义递归Awaited类型来解析和扁平化,如下所示:

type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;

操场



旧答案

更新: awaited类型运算符被延迟到更高版本- 根本不清楚它是否会被释放。


这是一个已知问题 好消息: TS 3.9 (即将推出测试版)将推出改进的承诺类型

我想再次引入awaited从操作型#17077 ,以满足我们的机制需要递归地展开一个承诺般的类型等的方法Promise.allPromise.racePromise.allSettledPromise.prototype.then ,并Promise.prototype.catch

类型声明Promise.all和其他人使用的新awaited类型运营商。 如果您使用 nightly build 进行测试Promise.all现在可以正确解析为Promise<(string | number)[]>

type Promisable = (() => Promise<string>) | (() => Promise<number>);

declare const promisable: Promisable
const res = await Promise.all([promisable()]); // res: (string | number)[]

相比之下,TS 3.8 处理不了 对于版本 < 3.9,您可以手动分配泛型类型参数:

declare const promisable: Promisable
const res = await Promise.all<string | number>([promisable()]); // res: (string | number)[]

你不需要这样一个冗长的类型,这会做:

type Promisable = (() => Promise<string|number>);
const func = async (promisable: Promisable) => {
  await Promise.all([promisable()]);
};

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM