이 글은 제가 타입챌린지를 하면서 해석한 내용을 적는 글입니다. 틀린 내용이 있으면 댓글 달아주시면 감사하겠습니다.
https://github.com/type-challenges/type-challenges/blob/main/questions/00015-medium-last/README.md
쉽다. 단순히 배열의 마지막 원소를 리턴하는 타입을 만들면 된다.
type Last<T extends any[]> = T extends [...infer O, infer L] ? L : never;
type Last<T extends any[]> = [any, ...T][T['length']];
type Last<T extends any[]> = T extends [infer F, ...infer K] ? T[K['length']] : never;
/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/utils'
type cases = [
Expect<Equal<Last<[3, 2, 1]>, 1>>,
Expect<Equal<Last<[() => 123, { a: string }]>, { a: string }>>,
]
첫 번째 풀이
infer를 사용해서 풀었다.
T extneds [...infer O, infer L] ? L : never : T를 마지막 원소 L과 나머지 원소를 담은 배열 O로 나누고, 마지막 원소인 L을 리턴한다. 이러면 끝이다.
두 번째 풀이
내 기준 신박한 풀이법이었다.
배열의 속성인 length를 이용하여 마지막 원소를 뽑는 방법인데, length는 보통 마지막 index + 1 인 숫자를 가지므로, 배열 T 맨앞에 any타입의 원소 하나를 더 붙이면 해당 배열의 길이는 T의 길이 + 1 이 되니까, 이를 이용해 T['length']로 마지막 원소를 뽑는 방법이다.
[any, ...T] : 배열 T 앞에 any타입의 원소가 하나 추가된 배열을 만든다. 이렇게 되면 해당 배열의 길이는 T['length'] + 1 이 되므로, T['length'] 위치의 원소가 해당 배열의 마지막 원소일 것이다.
[T['length']] : [any, ...T] 배열에서 T['length']위치의 원소를 선택한다.
즉 [any, ...T] 를 배열 A라고 하고, T['length'] = index라고 하면, [any, ...T][T['length']] 는
A[index] 가 되는 것이다.
세 번째 풀이
두 번째 풀이를 살짝 변형해서 만들어봤다.
두 번째 풀이에서 배열에 원소를 하나 추가했다면, 반대로 원소를 하나 뺀 배열을 만들어 보는건 어떨까? 해서 만들게 되었다.
T extends [infer F, ...infer K] ? T[K['length']] ? never; : 여기서 [infer F, ...infer K] 이 아니고 [...infer K, infer F] 여도 상관이 없다. T에서 원소 하나를 제외한 배열 K를 만들어서 K의 length를 활용하는 방법이다.
'Language > Typescript' 카테고리의 다른 글
타입챌린지 : 20-Promise.all (0) | 2023.03.24 |
---|---|
타입챌린지 : 16-Pop (medium) (0) | 2023.03.22 |
타입챌린지 : 12-Chainable Options (medium) (0) | 2023.03.21 |
타입챌린지 : 10-Tuple To Union (medium) (0) | 2023.03.18 |
타입챌린지 : 9-Deep Readonly (medium) (0) | 2023.03.16 |