arrays - Typescript - 具有不同返回值的动态 promise 数组

标签 arrays typescript types promise promise.all

谁能帮我解决这段代码有什么问题吗? 我找不到合适的类型来输入 Promise.all在底部调用。 它也尝试过 Promise.all<Services[], PullRequests[]>(ops)但是PullRequests[]不能是可选的...

function wait<Twait>(time: number, response: Twait): Promise<Twait> {
    return new Promise(resolve => setTimeout(() => resolve(response), time))
}

interface Service {
    name: string;
    id: number;
}

async function getServices(): Promise<Service[]>  {
    const response = await wait(400, { "id": 200 });
    return [{ name: "service", id: response.id }]
}


interface PullRequest {
    prType: string;
    githubId: number;
}

async function getPrs(): Promise<PullRequest[]>  {
    const response = await wait(400, { "githubId": 200 });
    return [{ prType: "foo", githubId: response.githubId }]
}


async function main(): Promise<void> {

    const ops: [ PromiseLike<Service[]>, PromiseLike<PullRequest[]>? ] = [getServices()]

    if (Math.random() > 0.5) { // <== this is random on purpose.
        ops.push(getPrs())
    }
    
    
    const [ services, prs ] = await Promise.all(ops) // This throws a ts compile error (attached below)
    console.log("services:")
    console.log(services)
    console.log("prs:")
    console.log(prs)    
}

No overload matches this call. The last overload gave the following error.
 Argument of type '[PromiseLike<Service[]>, (PromiseLike<PullRequest[]> | undefined)?]' is not assignable to parameter of type 'Iterable<Service[] | PromiseLike<Service[] | undefined> | undefined>'. 
The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. 
Type 'IteratorResult<PromiseLike<Service[]> | PromiseLike<PullRequest[]> | undefined, any>' is not assignable to type 'IteratorResult<Service[] | PromiseLike<Service[] | undefined> | undefined, any>'. 
Type 'IteratorYieldResult<PromiseLike<Service[]> | PromiseLike<PullRequest[]> | undefined>' is not assignable to type 'IteratorResult<Service[] | PromiseLike<Service[] | undefined> | undefined, any>'. 
Type 'IteratorYieldResult<PromiseLike<Service[]> | PromiseLike<PullRequest[]> | undefined>' is not assignable to type 'IteratorYieldResult<Service[] | PromiseLike<Service[] | undefined> | undefined>'. 
Type 'PromiseLike<Service[]> | PromiseLike<PullRequest[]> | undefined' is not assignable to type 'Service[] | PromiseLike<Service[] | undefined> | undefined'. 
Type 'PromiseLike<PullRequest[]>' is not assignable to type 'Service[] | PromiseLike<Service[] | undefined> | undefined'. 
Type 'PromiseLike<PullRequest[]>' is not assignable to type 'PromiseLike<Service[] | undefined>'. 
Type 'PullRequest[]' is not assignable to type 'Service[]'. 
Type 'PullRequest' is missing the following properties from type 'Service': name, id

最佳答案

根据microsoft/TypeScript#28427,看起来像是 TS 库定义中的一个已知问题。 。目前,该库硬编码了一堆不包含可选元素的特定元组类型。我们已经采取了一些努力来解决这个问题,但显然 PromiseLike 类型以及它们与 await 交互的方式足够复杂,以至于尚未接受修复此问题的拉取请求。 A comment in microsoft/TypeScript#39788解释说切换它可能会破坏依赖于当前定义的现有现实世界代码。

除非上游解决了这个问题,否则您可以使用 declaration mergingPromise.all() 添加您自己的签名,只需 maps promise 对传入的数组或元组的元素展开:

interface PromiseConstructor {
  all<T extends readonly any[]>(
    values: { [K in keyof T]: T[K] | PromiseLike<T[K]> }
  ): Promise<T>;
}

您可以测试它是否符合您的要求:

const promiseAllOps = Promise.all(ops); // no error now  
// const promiseAllOps: Promise<[Service[], (PullRequest[] | undefined)?]>
const awaitPromiseAllOps = await promiseAllOps;
// const awaitPromiseAllOps: [Service[], (PullRequest[] | undefined)?]
const [services, prs] = awaitPromiseAllOps;
services; // Service[]
prs; // PullRequest[] | undefined

Playground link

关于arrays - Typescript - 具有不同返回值的动态 promise 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64015121/

相关文章:

php - 反序列化数据库数据

javascript - .find() 多选器不能添加prop

ruby-on-rails - TypeError(无法将 nil 转换为 String)与 Attachment_Fu

c# - 使用按位方法对相同类型的值进行理想的 c# 缩减方法?

vba - 错误时类型不匹配

javascript - AngularJS ng 重复 json 格式

java - 在 Java 中如何将二维数组转换为一维数组

angular - 强制 Angular 遵循 json 中的接口(interface)类型

typescript - 从 TypeScript 接口(interface)返回 Promise

reactjs - 如何轻松获取 ts 类型的 react-native element prop?