/*
20 - Promise.all
-------
by Anthony Fu (@antfu) #medium #array #built-in
### Question
Type the function `PromiseAll` that accepts an array of PromiseLike objects, the returning value should be `Promise<T>` where `T` is the resolved result array.
```ts
const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise<string>((resolve, reject) => {
setTimeout(resolve, 100, 'foo');
});
// expected to be `Promise<[number, number, string]>`
const p = Promise.all([promise1, promise2, promise3] as const)
View on GitHub: https://tsch.js.org/20 */
/* _____________ Your Code Here _____________ */
declare function PromiseAll(values: any): any
/* _____________ Test Cases _____________ */ import { 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)])
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]>>> ]
/* _____________ Further Steps _____________ / /
Share your solutions: https://tsch.js.org/20/answer View solutions: https://tsch.js.org/20/solutions More Challenges: https://tsch.js.org */
어려우다.
```tsx
declare function PromiseAll<T extends unknown []>(values: readonly [...T]): Promise<{
[i in keyof T]: T[i] extends Promise<infer R> ? R : T[i]
}>
declare function PromiseAll<T extends unknown []>(values: readonly [...T]): any
우선 T
는 배열입니다.
그러나 실제 파라미터의 타입은 T
여서는 안됩니다. T의 타입은 unknown[]
이기 때문입니다.
그렇기 때문에 전개 연산자를 통해서 배열의 각 타입을 확인하여 새로운 타입을 만듭니다. 이 때에 readonly
키워드를 추가한 이유는 튜플 파라미터도 받을 수 있게 하기 위함입니다.
readonly
가 빠진 경우
이제 Return 부분을 살펴 보겠습니다.
declare function PromiseAll<T extends unknown[]>(values: [...T]): Promise<{
[i in keyof T]: T[i] extends Promise<infer R> ? R : T[i]
}>
T
의 keyof
를 꺼내면 '0'
'1'
'2'
와 같은 인덱스를 꺼낼 수 있게 되고 T[i] 와 같이 값에 접근하게 됩니다.Promise
값 인지 확인합니다. 만약 맞다면 Promise
의 값 타입을 알기 위해 infer
를 이용해서 변수화 합니다. 그리고 추정된 값을 리턴합니다.Promise
가 아니라면 값을 그대로 리턴 합니다.