我有以下代码导致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()]);
};
看到自己的错误
是否可以将联合类型与Promise.all
结合使用?
编辑:
我知道可以改用() => Promise<string|number>
之类的东西。但是,在具有大量异步函数和大类型的高级应用程序中,将函数的联合转换为联合的函数并不容易。从代码角度来看,它也不是很实用。
答案 0 :(得分:5)
这是其中一种情况,其中type inference与当前promise type declarations一起失败。 最简单的解决方案是手动添加通用类型参数:
const promisable: Promisable = ...
const res = await Promise.all<string | number>([promisable()]);
// res: (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类型可以通过custom recursive Awaited
type进行解析和扁平化:
type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;
更新:awaited
类型的运算符为delayed to later versions-不清楚是否将其完全释放。
这是known issue。好消息:TS 3.9(即将推出测试版)将与improved promise types一同发布:
我想从#17077重新引入
awaited
类型运算符,以满足我们对Promise.all
,{{1}等方法的递归解开Promise类型的机制的需求},Promise.race
,Promise.allSettled
和Promise.prototype.then
。
Promise.prototype.catch
中的 Type declarations和其他人使用新的Promise.all
类型的运算符。如果您test with the nightly build,awaited
现在可以正确解析为Promise.all
:
Promise<(string | number)[]>
相比之下,TS 3.8 can't handle it。对于3.9以下的版本,您可以manually assign通用类型参数:
type Promisable = (() => Promise<string>) | (() => Promise<number>);
declare const promisable: Promisable
const res = await Promise.all([promisable()]); // res: (string | number)[]
答案 1 :(得分:0)
您不需要这种冗长的类型,这可以做到:
type Promisable = (() => Promise<string|number>);
const func = async (promisable: Promisable) => {
await Promise.all([promisable()]);
};