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

2022-04-16 10:54:05 +08:00
 yiiouo

需求是这样的,有一个 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]

1687 次点击
所在节点    TypeScript
4 条回复
hsfzxjy
2022-04-16 10:59:20 +08:00
noe132
2022-04-16 11:22:55 +08:00
noe132
2022-04-16 11:25:14 +08:00
yiiouo
2022-04-16 11:26:26 +08:00
@hsfzxjy @noe132 感谢回复,解决了,谢谢!

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/847296

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX