gpt4 book ai didi

typescript - 为什么 Promise.all 中超过 10 个元素的数组会产生问题 "No overload matches this call"?

转载 作者:行者123 更新时间:2023-12-05 03:34:48 25 4
gpt4 key购买 nike

请考虑以下代码(就问题而言,就像虚拟示例​​一样):

class Image {
protected data: any;
public static setUp = async (_h: any): Promise<Image> => {
const me: Image = new Image();
me.data = await new Promise((resolve) => setTimeout(resolve, 500));
return me;
};
}

class Image2 {
protected data: any;
public static setUp = async (_h: any): Promise<Image2> => {
const me: Image2 = new Image2();
me.data = await new Promise((resolve) => setTimeout(resolve, 500));
return me;
};
}
class Image3 {
protected data: any;
public static setUp = async (_h: any): Promise<Image3> => {
const me: Image3 = new Image3();
me.data = await new Promise((resolve) => setTimeout(resolve, 500));
return me;
};
}

async function testing() {
await Promise.all([
Image.setUp({}), // 1st
Image2.setUp({}), // 2nd
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), // 5th
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), //10th
Image3.setUp({}), // from 11th we will get the following Problem reported
]);
}

问题描述

No overload matches this call.
The last overload gave the following error.
Argument of type '(Promise<Image> | Promise<Image2> | Promise<Image3>)[]' is not assignable to parameter of type 'Iterable<Image | PromiseLike<Image>>'.
The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
Type 'IteratorResult<Promise<Image> | Promise<Image2> | Promise<Image3>, any>' is not assignable to type 'IteratorResult<Image | PromiseLike<Image>, any>'.
Type 'IteratorYieldResult<Promise<Image> | Promise<Image2> | Promise<Image3>>' is not assignable to type 'IteratorResult<Image | PromiseLike<Image>, any>'.
Type 'IteratorYieldResult<Promise<Image> | Promise<Image2> | Promise<Image3>>' is not assignable to type 'IteratorYieldResult<Image | PromiseLike<Image>>'.
Type 'Promise<Image> | Promise<Image2> | Promise<Image3>' is not assignable to type 'Image | PromiseLike<Image>'.
Type 'Promise<Image2>' is not assignable to type 'Image | PromiseLike<Image>'.
Type 'Promise<Image2>' is not assignable to type 'PromiseLike<Image>'.
Types of property 'then' are incompatible.
Type '<TResult1 = Image2, TResult2 = never>(onfulfilled?: ((value: Image2) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | null | undefined) => Promise<...>' is not assignable to type '<TResult1 = Image, TResult2 = never>(onfulfilled?: ((value: Image) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | null | undefined) => PromiseLike<...>'.
Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
Types of parameters 'value' and 'value' are incompatible.
Type 'Image2' is not assignable to type 'Image'.
Property 'data' is protected but type 'Image2' is not a class derived from 'Image'.ts(2769)
lib.es2015.iterable.d.ts(226, 5): The last overload is declared here.
(property) Image3.setUp: (_h: any) => Promise<Image3>

我注意到以下几点:

  • 问题不仅与 Promise 数组中的元素数量有关,还与返回的不同类型的数量有关,事实上,如果长度 >10 的数组包含将返回的 Promise,则不会报告该问题同类型
await Promise.all([
Image3.setUp({}), // 1st
Image3.setUp({}), // 2nd
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), // 5th
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), //10th
Image3.setUp({}), // NO ISSUES from here
Image3.setUp({}),
]);

看起来在类型 def 中为 Promise.all 定义的重载不管理十个元素长度后的混合类型。

我发现一个快速解决方法是像这样嵌套 Promise.all

    async function testing() {
await Promise.all([
Promise.all([
Image.setUp({}), // 1st
Image2.setUp({}), // 2nd
]),
Promise.all([
Image2.setUp({}), // 3rd
Image3.setUp({}),
Image3.setUp({}), // 5th
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), //10th
Image3.setUp({}),
]),
]);
}

以上将扩展返回混合类型的最多 10 个元素。

问题链接到接口(interface) PromiseConstructor 到 lib.es2015.iterable type def 的这一行:

    all<T>(values: Iterable<T | PromiseLike<T>>): Promise<T[]>;

我想更深入地了解这一点:类型定义在哪里失败?是否与版本 lib.es2015 相关的问题已在以下版本中解决?它与PromiseLike有关吗?为什么从第 11 个元素开始出现问题?

最佳答案

这是 Promise.all 过去定义类型的限制。最初 typescript 无法很好地模拟此类函数,因此使用了许多重载方法。

然而,Typescript 在所有类型上都变得越来越好,现在有了诸如剩余元组类型、映射元组类型和大量性能改进等改进,从 Typescript 4.5 开始,您的代码将毫无问题地运行。

您可以在 playground 中尝试 typescript 或者您可以升级到 4.5,因为它已在 npm 上可用

关于typescript - 为什么 Promise.all 中超过 10 个元素的数组会产生问题 "No overload matches this call"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70062994/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com