타입 챌린지 14 - First of Array

소파의 벨로그·2025년 2월 22일

타입챌린지

목록 보기
4/131

문제 링크

문제

배열(튜플) T를 받아 첫 원소의 타입을 반환하는 제네릭 First<T>를 구현하세요.

내 풀이

type First<T extends any[]> = 
  T extends [infer First,...infer Rest]?
    First
    :never;

[infer First,...infer Rest]를 사용해서 첫 번째로 오는 타입을 참인 분기에서 사용할 수 있었다.

만약 T에 빈 배열 타입이 들어올 경우에는 T extends [infer First,...infer Rest]가 거짓으로 판별된다.

문제에서는
First<[]>의 타입을 never로 지정하였으므로, 거짓인 분기에서 never를 사용하게 하였다.

 // @ts-expect-error
  First<'notArray'>,
  // @ts-expect-error
  First<{ 0: 'arrayLike' }>,

배열이 아닌 경우에는 에러가 나야하는 제약 조건도, <T extends any[]> 제네릭을 사용하여 배열만 들어올 수 있게끔 제약을 주었다.

관련 개념

infer과 관련된 개념이 나왔다
infer${검사하는 타입} extends ${조건}?${참인 경우의 타입}:${거짓인 경우의 타입}와 같은 삼항 연산 타입에서 조건 부분에 들어갈 수 있는 사설(?)타입이다.

이때 조건에서 infer이 제시된 형태와 ${검사하는 타입}이 같다면
${참인 경우의 타입}에서 infer에서 이름 붙인 타입 명을 사용할 수 있다.

다른사람의 풀이

풀이 1

//answer1
type First<T extends any[]> = T extends [] ? never : T[0]

//answer2
type First<T extends any[]> = T['length'] extends 0 ? never : T[0]

이와 같은 풀이 방식도 존재했다.

첫 번째 풀이는 T가 빈 배열일 경우 never, 아니면 T[0]을 사용하게 두었고,

두 번째 풀이는 T['length']가 0인 경우 never, 아니면 T[0]을 사용하게 두었다.
참고로 타입이 튜플이 아니라 number[]와 같은 형태이거나, 리터럴 stringlegnth 프로퍼티는 숫자 리터럴 타입이 아니라, number임에 주의하여야 한다

0개의 댓글