// 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
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
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]>
}>
型引数T
を使用するためにPromiseAll
に型引数設定を追加。Promise<T>
になるように記述。T
の配列内を1つずつPromiseが解決された後の方に変換する必要があるため、Awaited<T>
のようなことがしたい。
Awaited<T>
では配列内の各要素ではなく、配列自体がPromiseであるような扱われ方をしてしまう。Awaited
をするため、[Key in keyof T]: Awaited<T[Key]>
とする。Solution by Yasunori-aloha #32880
// 你的答案
declare function PromiseAll<T extends any[]>(values: [...T]):
Promise<{[K in keyof T]: Awaited<T[K]>}>
Solution by geweidong #32764
题目的两个关键:
PromiseAll<const T extends unknown[]>
来实现,这样导致 test case 3, 4 也进行 const 推演。 其实这样蛮好的,不过不符合 test case。最后采用下面这种 readonly [...T]
的方式。declare function PromiseAll<T extends unknown[]>(values: readonly [...T]):
Promise<{ [K in keyof T]: Awaited<T[K]>;
Solution by mistkafka #32644
declare function PromiseAll<const T extends unknown[]>(values: T):
Promise<{[K in keyof T]: Awaited<T[K]>}>
Solution by wubrafiq807 #32555
declare function PromiseAll<T extends unknown[]>(values: [...T]):
Promise<{[K in keyof T]: Awaited<T[K]> }>
Solution by dev-hobin #32362
// your answers
declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{ [K in keyof T]: Awaited<T[K]> }>
Solution by laqudee #32357
// Solution 1
declare function PromiseAll<T extends unknown[]>(values: readonly [...T]):
Promise<{ [K in keyof T]: Awaited<T[K]>}>
// Solution 2
declare function PromiseAll<T extends unknown[]>(values: readonly [...T]):
Promise<{ [K in keyof T]: T[K] extends Promise<infer R> | infer R ? R : never }>
Solution by Tap-Kim #32161
declare function PromiseAll<T extends any[]>(values: [...T]): Promise<{
[Key in keyof T]: Awaited<T[Key]>
}>
We declare T
as extension from an array of any type, its important to spread T
when typing values
, this way it will spread each element type, otherwise it will compress all the values as union[]
instead of [type1, type2, ...]
.
We use our dear Awaited
type to extract the expected awaited type of T[Key]
even if it is not a promise at all
Solution by joyanedel #32154