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

2023-12-27

我有以下一段代码,导致 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>反而。但在具有大量异步函数和大类型的高级应用程序中,将函数并集转换为并集函数并不容易。从代码的角度来看,它也不是很实用。


Update

这是其中一种情况,其中类型推断 https://www.typescriptlang.org/docs/handbook/type-inference.html与电流承诺类型声明 https://github.com/microsoft/TypeScript/blob/065a996345fcfafd3c744d2a724a1ae9f31f9ab0/lib/lib.es2015.promise.d.ts#L41-L113失败。 最简单的解决方案是手动添加泛型类型参数:

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()]);

With 打字稿 4.1 https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/:更复杂的、可能嵌套的 Promise 类型可以通过自定义递归Awaited type https://devblogs.microsoft.com/typescript/announcing-typescript-4-1/#recursive-conditional-types像这样:

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

操场 https://www.typescriptlang.org/play?#code/KYDwDg9gTgLgBAbzgXwLACgMwJ5mHABSggFsBLAZwEMAjAG3wF44AKFgSjkYD5DjyKwADwUYUMgDsA5t04AfVhy68ipSsIkBXEjWBRZAbiy58qgcABKwGJqgShAFV7MHcUDGASAJhVacefGqCQpIAZnpwAJK8APxRcABccBLAAG56GBhewADGdFRQ+DkQEqJwYPyUtAxJZlX0wJnoxaXwUACMXHBUAO5UZPB1ggB0VHR0ImKSUnAKWjp63CwA2hVB1cAcALrsBnAA9PtwhRRJLKLi0rPJ2rpQ7MtbGC1lUABMXb39g5UjYxNDSzWWz2IYbbhLVa-DbbXYHI4nM4XabXeZ3B5PTDoHB4OAAQT6A2AXkczjgrncnh8gXMABkyABrYRhCIAVVi+MJHhJ7MS5KMzRKrwAzJ8uTT1KNxkICd9iUIrDY7A4TEIwQ0IZC1gIYewdntDsdgKdWMirnNbnoMUA



旧答案

Update: The awaited类型运算符是延迟到更高版本 https://github.com/microsoft/TypeScript/issues/37198#issuecomment-604160291- 根本不清楚是否会发布。


这是一个已知问题 https://github.com/microsoft/TypeScript/pull/33707。好消息:TS 3.9 https://github.com/microsoft/TypeScript/issues/37198(即将推出测试版)将推出改进的承诺类型 https://github.com/microsoft/TypeScript/pull/35998:

我想重新介绍一下awaited类型运算符来自#17077 https://github.com/microsoft/TypeScript/pull/17077满足我们对一种机制的需求,以递归方式为类似 Promise 的方法解包Promise.all, Promise.race, Promise.allSettled, Promise.prototype.then, and Promise.prototype.catch.

of Promise.all和其他人使用新的awaited类型运算符。如果你使用夜间构建进行测试 https://www.typescriptlang.org/play/?ts=3.9.0-dev.20200323#code/KYDwDg9gTgLgBAbzgXwLACgMwJ5mHABSggFsBLAZwEMAjAG3wF44AKFgSjkYD5DjyKwADwUYUMgDsA5t04AfVhy68ipSsIkBXEjWBRZAbgwYAJsADGdKlHzmIE0XDD9KtBgC4%20a6vWAY7DvA2FACMXHBUAO5UZPDO3m7ASgD0yXDBIZ6i4tJwClo6ev72jsEATOFRMfCqAsAAdFR0dCwA2vECiRwAuuwGcKnpwBRlnizZklJ5cAW6UOyt3RhAA, 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无法处理它 https://www.typescriptlang.org/play/?ts=3.8.3#code/KYDwDg9gTgLgBAbzgXwLACgMwJ5mHABSggFsBLAZwEMAjAG3wF44AKFgSjkYD5DjyKwADwUYUMgDsA5t04AfVhy68ipSsIkBXEjWBRZAbgwYAJsADGdKlHzmIE0XDD9KtBgC4%20a6vWAY7DvA2FACMXHBUAO5UZPDO3m7ASgD0yXDBIZ6i4tJwClo6ev72jsEATOFRMfCqAsAAdFR0dCwA2vECiRwAuuwGcKlwesRQADRedSJiklKt3bz1i3AmmgAWq0A。对于 手动分配泛型类型参数:

declare const promisable: Promisable
const res = await Promise.all<string | number>([promisable()]); // res: (string | number)[]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TypeScript:Promise.all 不处理联合类型 的相关文章

随机推荐