2023-03-23

타입 챌린지 - Includes

타입 챌린지 includes 문제를 풀이해 보자!

풀이

JavaScript의 Array.includes 함수를 타입 시스템에서 구현하는 문제다.

타입스크립트에서 extends를 통해 상속에 대한 삼항 연산은 가능하지만, 서로 같음을 완벽하게 파악할 순 없다.

간단한 예를 들어보면 아래와 같다.

type isTrue = { a: 'A' } extends { readonly a: 'A' } ? true : false // true

readonly가 존재하기 때문에 서로 같지는 않지만, 같은 키를 상속하고 있어 true가 나오게 된다.

따라서 타입 챌린지에서 제공하는 유틸 타입 Equal을 활용하거나 직접 만들어야 하는데,

타입 초보인 나에게 직접 구현이란 쉽지 않았고, Equal의 메커니즘을 이해하기 쉽지 않았다.

export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
T
>() => T extends Y ? 1 : 2
? true
: false

추 후 Equal에 대해 자세히 파헤쳐 보기로 하고,

풀이에 대해 내용을 이어가면 infer를 활용해 재귀적으로 원소를 하나씩 추론해 비교하면서,

같은 경우 true를 반환하고 그렇지 않은 경우 false를 반환하면 된다.

풀이

type Includes<T extends unknown[], U> = T extends [infer F, ...infer R]
? Equal<F, U> extends true
? true
: Includes<R, U>
: false