FE/type-challenge
5153. IndexOf
최토피
2023. 8. 17. 18:42
728x90
문제
Implement the type version of Array.indexOf, indexOf<T, U> takes an Array T, any U and returns the index of the first U in Array T.
type Res = IndexOf<[1, 2, 3], 2>; // expected to be 1
type Res1 = IndexOf<[2,6, 3,8,4,1,7, 3,9], 3>; // expected to be 2
type Res2 = IndexOf<[0, 0, 0], 2>; // expected to be -1
cases
type cases = [
Expect<Equal<IndexOf<[1, 2, 3], 2>, 1>>,
Expect<Equal<IndexOf<[2, 6, 3, 8, 4, 1, 7, 3, 9], 3>, 2>>,
Expect<Equal<IndexOf<[0, 0, 0], 2>, -1>>,
Expect<Equal<IndexOf<[string, 1, number, 'a'], number>, 2>>,
Expect<Equal<IndexOf<[string, 1, number, 'a', any], any>, 4>>,
]
정답
type IndexOf<T, U, V extends number[] = []> = T extends [infer T1, ...infer Rest]
? (<W>() => W extends T1 ? 0 : 1) extends (<W>() => W extends U ? 0 : 1)
? V['length']
: IndexOf<Rest, U, [...V, 0]>
: -1
풀이
조건
- 두 번째 인자의 위치를 반환한다.
- 없는 경우 -1을 반환한다.
해설
재귀적으로 검사하는 로직을 설계한다.
type IndexOf<T, U, V extends number[] = []> =
T extends [infer T1, ...infer Rest]
? T1 extends U
? V['length']
: IndexOf<Rest, U, [...V, 0]>
: -1
네번째 case와 같은 3 extends number
등의 경우에 의도치 않은 결과가 나오므로, 양방향으로 extends
를 하는지 확인한다.
type IndexOf<T, U, V extends number[] = []> =
T extends [infer T1, ...infer Rest]
? [T1, U] extends [U, T1]
? V['length']
: IndexOf<Rest, U, [...V, 0]>
: -1
다섯번째 case와 같이 any
에 문제가 생기는 경우가 발생한다. 따라서 Equal
처럼 함수화해서 비교하는 방식으로 해결한다.
type IndexOf<T, U, V extends number[] = []> = T extends [infer T1, ...infer Rest]
? (<W>() => W extends T1 ? 0 : 1) extends (<W>() => W extends U ? 0 : 1)
? V['length']
: IndexOf<Rest, U, [...V, 0]>
: -1
사실 <W>() => W extends U ? 0 : 1 부분은 잘 이해가 가지 않는다.
어째서 두 함수를 비교하는 것으로 Equality가 보장되는거지? 아시는 분은 댓글 부탁드려요 ㅜ
혹시 오류나 개선점이 있다며 댓글 부탁드립니다 :)
728x90