V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
yiiouo
V2EX  ›  TypeScript

如何实现类似 Promise.all 的类型定义

  •  
  •   yiiouo · 2022-04-16 10:54:05 +08:00 · 1911 次点击
    这是一个创建于 957 天前的主题,其中的信息可能已经有所发展或是发生改变。

    需求是这样的,有一个 test 函数

    1. 接收一个参数,该参数的类型为函数数组,每个函数返回一个 Promise
    2. 执行 test 函数后,会返回一个数组,数组内的每个值会对应传入的函数数组执行后的结果

    最终想要达到的效果:

    // 伪代码
    function test(data) {}
    
    const [r1,r2] = await test([ () => Promise.resolve(1), () => Promise.resolve(true) ])
    // 类型:[number, boolean]
    

    我参考了 Promise.all 的类型定义,

    Promise.all 的类型定义:

    all<T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>;
    

    弄出下面的类型定义:

    function test<T extends readonly (() => Promise<any>)[]>(data: T): Promise<{
      -readonly [p in keyof T]: Awaited<
        T[p] extends () => Promise<any> ? ReturnType<T[p]> : T[p]
      >
    }> {}
    

    但出来的效果是这样的:

    const [r1,r2] = await test([ () => Promise.resolve(1), () => Promise.resolve(true) ])
    // 类型:[number | boolean, number | boolean]
    

    每个值的类型推断都是 | ,而 Promise.all 能精确地指出数组每个值分别是什么类型

    所以我想请教下大家,如何修改上面的定义,让 TypeScript 推断的类型从

    [number | boolean, number | boolean] 变为 [number, boolean]

    4 条回复    2022-04-16 11:26:26 +08:00
    hsfzxjy
        1
    hsfzxjy  
       2022-04-16 10:59:20 +08:00 via Android   ❤️ 1
    yiiouo
        4
    yiiouo  
    OP
       2022-04-16 11:26:26 +08:00
    @hsfzxjy @noe132 感谢回复,解决了,谢谢!
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5386 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 08:05 · PVG 16:05 · LAX 00:05 · JFK 03:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.