출처: Type Challenges, https://github.com/type-challenges/type-challenges/blob/main/README.ko.md
189 - Awaited
Promise와 같은 타입에 감싸인 타입이 있을 때, 안에 감싸인 타입이 무엇인지 어떻게 알 수 있을까요?
type ExampleType = Promise<string>
type Result = MyAwaited<ExampleType> // string
풀이
type Thenable<T> = {
then: (_: (_:T) => any) => any
}
type MyAwaited<T extends Thenable<any>> = T extends Thenable<infer U>
? U extends Thenable<any>
? MyAwaited<U>
: U
: never
type MyAwaited<T extends object> = T extends { then : (onfulfilled: (value: infer U) => any) => any }
? U extends { then : (onfulfilled: (value: any) => any) => any }
? MyAwaited<U>
: U
: never
원래는 아래와 같이 풀었는데 이해를 돕기 위해 이슈를 보고 위 코드의 Thenable을 추가했다.
위 코드에서 then은 객체 내부`{ ... }`의 key로 정확히 then이라는 이름을 가져야하지만,
onfulfilled나 value는 함수 내부`( .... )`의 파라미터의 타입을 지정하기 위해 넣은 이름일 뿐,
함수의 파라미터가 `onfulfilled`나 `value`와 같은 이름을 가져야하는 것이 아니다.
Thenable을 보면 특정 이름이 아니라 `_`를 사용하는 것을 볼 수 있다.
또, 주목하면 좋을 부분은 type 내에서 재귀가 가능하다는 것이다.
이쯤되면 단순히 타입을 지정하는 게 아니라 그냥 거의 함수 수준인데
extends를 이용한 조건문 삼항 연산자를 통해서 자기 자신을 다시 불러서 재귀적으로 type을 정의할 수 있다.
Reference
189 - Awaited - updated solution 11/08/2022 · Issue #18837 · type-challenges/type-challenges
Please comment if you find any improvements! type Thenable<T> = { then: (onfulfilled: (arg: T) => unknown) => unknown; } type MyAwaited<T extends Thenable<any> | Promise<any>> = T extends Promise<i...
github.com
'알고리즘 > Type Challenges' 카테고리의 다른 글
533 - Concat (0) | 2023.09.06 |
---|---|
268 - If (0) | 2023.09.06 |
43 - Exclude (0) | 2023.09.06 |
18 - Length of Tuple (0) | 2023.09.06 |
14 - First of Array (0) | 2023.09.04 |