00020-medium-promise-all

Back

declare function PromiseAll<T extends any[]>(values: readonly[...T]): Promise<{ [K in keyof T]: Awaited<T[K]> }>

Solution by lToBContinued #37521

declare function PromiseAll<T extends any[]>(
  values: readonly [...T]
): Promise<{
  [K in keyof T]: T[K] extends Promise<infer R> ? R : T[K]
}>;

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'

const promiseAllTest1 = PromiseAll([1, 2, 3] as const)
const promiseAllTest2 = PromiseAll([1, 2, Promise.resolve(3)] as const)
const promiseAllTest3 = PromiseAll([1, 2, Promise.resolve(3)])
const promiseAllTest4 = PromiseAll<Array<number | Promise<number>>>([1, 2, 3])
const promiseAllTest5 = PromiseAll<(number | Promise<string>)[]>([1, 2, Promise.resolve('3')])

type cases = [
  Expect<Equal<typeof promiseAllTest1, Promise<[1, 2, 3]>>>,
  Expect<Equal<typeof promiseAllTest2, Promise<[1, 2, number]>>>,
  Expect<Equal<typeof promiseAllTest3, Promise<[number, number, number]>>>,
]

Solution by AnastasiaSv #37440

declare function PromiseAll<T extends unknown[]>(values: readonly [...T]): Promise<{
  [K in keyof T]: Awaited<T[K]>;
}>;
declare function PromiseAll<T extends unknown[]>(values: readonly [...T]): Promise<{
  [K in keyof T]: T[K] extends Promise<infer R> | infer R ? R : never;
}>;

  1. values: readonly [...T] 兼容一个只读元组

Solution by djdidi #37149

declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{
  [P in keyof T]: Awaited<T[P]>
}>

Solution by 359Steve #37032

declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{
  [P in keyof T]: T[P] extends Promise<infer R> | infer R ? R : T[P]
}>

Solution by duynhanf #36779

declare function PromiseAll<T extends any[]>(values: [...T]): Promise<{ [K in keyof T]: Awaited<T[K]> }>

Solution by tungulin #36729

// 你的答案

type DeepPromise = T extends Promise ? DeepPromise : T; declare function PromiseAll<T extends any[]>(values:readonly [...T]): Promise<{[key in keyof T]:DeepPromise<T[key]>}>

Solution by zhaohuaishuai #36647

// your answers
declare function PromiseAll<T extends any[]>(values: readonly [...T]):
  Promise<{ [K in keyof T]: Awaited<T[K]> }>;

Solution by duanlvxin #36506

declare function PromiseAll<T extends readonly unknown[]>( values: readonly [...T] ): Promise<{ [K in keyof T]: T[K] extends Promise ? R : T[K] }>

Solution by asylbekduldiev #36472

declare function PromiseAll<T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }> // 官方实现.

// 不加 |[] 会在 case3 失败, 得到 Promise<number[]> 而不是 Promise<[number, number, number]>
// 其中原理可参考 https://stackoverflow.com/questions/78741527/what-s-the-meaning-of-t-extends-readonly-unknown-in-typescript-s-functi
// 简而言之, tsc 有一个特性叫 Contextual Typing, 即根据上下文推导类型. 因为 [] 是一个 tuple, 所以加上后会使 tsc 推导为 tuple 而不是 array.
declare function PromiseAll<T extends readonly unknown[]>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }> // 失败

// 以下使用 ts4.0 的 variadic-tuple-types 也可成功. 这是因为 [...T] 会使类型推导为 tuple
declare function PromiseAll<T extends readonly unknown[]>(values: [...T]): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>

// 以下使用 ts5.0 的 const Type Parameters, 会进行更严格的类型推导, 使 case3 和 case2 的推导类型完全相同
declare function PromiseAll<const T extends readonly unknown[] | []>(values: T): Promise<{ -readonly [P in keyof T]: Awaited<T[P]> }>

Solution by freesrz93 #36447

declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{
  [k in keyof T]: Awaited<T[k]>
}>

Solution by AleksandrShcherbackov #36165

declare function PromiseAll<T extends any[]>(values : readonly [...T]): Promise<{
  [K in keyof T]: T[K] extends Promise<infer R> | infer R ? R : never
}>

Solution by vaclock #35761

declare function PromiseAll<T extends Array<any>>(values: readonly [...T]): Promise<{ [P in keyof T]: Awaited<T[P]> }>;

Solution by gangnamssal #35557

declare function PromiseAll<T extends unknown[]>(values: readonly [...T]):Promise<{[k in keyof T] : Awaited<T[k]>}> 

Solution by RanungPark #35483

declare function PromiseAll<T extends any[]>(values: [...T]): Promise<{
  [key in keyof T]: Awaited<T[key]>
}>

Solution by eunsukimme #35124

// your answers
declare function PromiseAll<T extends readonly any[]>(values: readonly [...T]): Promise<{
  [P in keyof T]: T[P] extends Promise<infer R> ? R : T[P] extends number ? T[P] : number
}>

Solution by LeeKangHyun #34912

We should restrict T to an array of any. And then, values' type should be readonly [...T] because of as const params. Finally, using [P in keyof T] we can access T's members' types.

declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{ [P in keyof T]: T[P] extends Promise<infer U> | infer U ? U : never }>

Solution by dev-jaemin #34883

type Reduce<T extends unknown[], U extends unknown[] = []> = T extends [infer First, ...infer Rest]
  ? Reduce<Rest, [...U, Awaited<First>]> 
  : U
declare function PromiseAll<T extends unknown[]>(values: [...T]): number extends T['length']
  ? Promise<Awaited<T[number]>[]>
  : Promise<Reduce<T>>

Solution by 2083335157 #34862

declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{
  [P in keyof T]: T[P] extends Promise<infer R> | infer R ? R : never
}>

Solution by devshinthant #34567

declare function PromiseAll<T extends any[]>(values: T): Promise<{
  [K in keyof T]: Awaited<T[K]>
}>

Solution by ktim816 #34445

// 如果函数入参为[1, true, 'str'],此时T为[number, boolean, string],keyof T为['0', '1', '2']
type MyAwaited<T> = T extends Promise<infer R> ? MyAwaited<R> : T
declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{
  [P in keyof T]: MyAwaited<T[P]>
}>

Solution by ouzexi #33991

type MyAwaited<T> = T extends Promise<infer P> ? MyAwaited<P> : T
declare function PromiseAll<T extends Array<unknown>>(value: [...T]): Promise<{
  [P in keyof T]: MyAwaited<T[P]>
}>

Solution by Danny101201 #33836

declare function PromiseAll<T extends any[]>(arr: readonly [...T]): Promise<{ [K in keyof T]:T[K] extends Promise ? P :T[K]}>

Solution by rookiewxy #33672

// your answers
declare function PromiseAll<V extends any[]>(values: [...V]): 
  Promise<{ [K in keyof V]: V[K] extends Promise<infer P> ? P : V[K] extends number ? V[K] : number}>;

Solution by nupthale #33583

declare function PromiseAll<T extends any[]>(values: [...T]) :Promise<{[K in keyof T] : Awaited<T[K]>}> 

Solution by raymondanythings #33475

declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{ [K in keyof T]: T[K] extends Promise<infer P> | infer P ? P : never}>

Solution by Tubring25 #33295

// your answers

declare function PromiseAll<T extends unknown[] | []>(value: T): Promise<{
  -readonly [P in keyof T]: Awaited<T[P]>
}>

Solution by KeithChou #33252

// 你的答案
type P1<T extends any[]> = {
  [K in keyof T]: T[K] extends PromiseLike<infer R> ? R : T[K];
};

declare function PromiseAll<T extends any[]>(arr:readonly [...T] ): P1<T>;

Solution by 2531800823 #33244

type Awaited<T> = T extends PromiseLike<infer R> ? Awaited<R> : T

declare function PromiseAll<V extends unknown[]>(values: [...V]): Promise<{
  [P in keyof V]: Awaited<V[P]>
}>

Solution by Taneros #33044

// 解答をここに記入
declare function PromiseAll<T extends readonly any[]>(values: [...T]): Promise<{
  [Key in keyof T]: Awaited<T[Key]>
}>

Solution by Yasunori-aloha #32880