[type-challenges] Awaited / If / Concat
Awaited
설계 의도
제네릭타입 T를
PromiseLike<any>로 정의하여서Promise,then메서드 가진 함수 모두 받도록 처리infer사용해서PromiseLike의 내부 타입 추출다중
Promise중첩 처리에서 최종 결과 타입 풀어내기 위해서 재귀적 조건부 타입 사용
Promise<T> vs PromiseLike<T>
Promise<T>는Promise객체의 전체 API를 나타내는 반면,PromiseLike<T>는then메서드를 가진 모든 객체를 의미한다.
interface PromiseLike<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): PromiseLike<TResult1 | TResult2>;
}
코드
/* _____________ Your Code Here _____________ */
type MyAwaited<T extends PromiseLike<any>> = T extends PromiseLike<infer U>
? U extends PromiseLike<any>
? MyAwaited<U>
: U
: never;
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
type X = Promise<string>
type Y = Promise<{ field: number }>
type Z = Promise<Promise<string | number>>
type Z1 = Promise<Promise<Promise<string | boolean>>>
type T = { then: (onfulfilled: (arg: number) => any) => any }
type cases = [
Expect<Equal<MyAwaited<X>, string>>,
Expect<Equal<MyAwaited<Y>, { field: number }>>,
Expect<Equal<MyAwaited<Z>, string | number>>,
Expect<Equal<MyAwaited<Z1>, string | boolean>>,
Expec
If
설계 의도
제네릭 타입 C가 true인지 조건 체크해서, 리턴타입 지정
boolean의 경우 분산 유니온타입(
true | false extends true)으로 처리되기 때문에true와false를 모두 리턴하게 된다.
코드
/* _____________ Your Code Here _____________ */
type If<C, T, F> = C extends true? T : F
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<If<true, 'a', 'b'>, 'a'>>,
Expect<Equal<If<false, 'a', 2>, 2>>,
Expect<Equal<If<boolean, 'a', 2>, 'a' | 2>>,
]
Concat
설계 의도
- 두 개의 튜플이나 배열을 하나로 결합하도록 처리
코드
/* _____________ Your Code Here _____________ */
type Concat<T extends readonly any[], U extends readonly any[]> = [...T,...U]
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
const tuple = [1] as const
type cases = [
Expect<Equal<Concat<[], []>, []>>,
Expect<Equal<Concat<[], [1]>, [1]>>,
Expect<Equal<Concat<typeof tuple, typeof tuple>, [1, 1]>>,
Expect<Equal<Concat<[1, 2], [3, 4]>, [1, 2, 3, 4]>>,
Expect<Equal<Concat<['1', 2, '3'], [false, boolean, '4']>, ['1', 2, '3', false, boolean, '4']>>,
]