본문 바로가기
Language/Typescript

타입챌린지 : 15-Last of Array (medium)

by hsloth 2023. 3. 22.

 

이 글은 제가 타입챌린지를 하면서 해석한 내용을 적는 글입니다. 틀린 내용이 있으면 댓글 달아주시면 감사하겠습니다.

 

https://github.com/type-challenges/type-challenges/blob/main/questions/00015-medium-last/README.md

 

GitHub - type-challenges/type-challenges: Collection of TypeScript type challenges with online judge

Collection of TypeScript type challenges with online judge - GitHub - type-challenges/type-challenges: Collection of TypeScript type challenges with online judge

github.com

 

 

쉽다. 단순히 배열의 마지막 원소를 리턴하는 타입을 만들면 된다.

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를 활용하는 방법이다.