jaenny.dev
article thumbnail

문제

배열 타입 T를 받아 그 배열의 첫 번째 원소의 타입을 리턴하는 제네릭 First<T>를 구현하세요.

type arr1 = ['a', 'b', 'c']
type arr2 = [3, 2, 1]

type head1 = First<arr1> // expected to be 'a'
type head2 = First<arr2> // expected to be 3

풀이

문제에서 배열 타입 T를 받는다고 했으니, 대괄호<> 안에는 any\[\]를 extends해야 한다. 여기까지 하면 errors의 빨간 줄이 사라진다.

이제 첫 번째 원소에 접근한다. TypeScript에서도 index를 활용해서 배열의 요소에 접근할 수 있다. 하지만 이 경우 빈 배열일 때의 예외처리가 불가능하다.

정답

스터디원들의 풀이가 포함되어있습니다!

// ============= Test Cases =============
import type { Equal, Expect } from "./test-utils";

type cases = [
  Expect<Equal<First<[3, 2, 1]>, 3>>,
  Expect<Equal<First<[() => 123, { a: string }]>, () => 123>>,
  Expect<Equal<First<[]>, never>>,
  Expect<Equal<First<[undefined]>, undefined>>
];

type errors = [
  // @ts-expect-error
  First<"notArray">,
  // @ts-expect-error
  First<{ 0: "arrayLike" }>
];

// ============= Your Code Here =============

// Solution 1
type First<T extends any[]> = T extends [] ? never : T[0];

// Solution 2
type First<T extends any[]> = T extends [infer U, ...any] ? U : never;

// Solution 3
type First<T extends any[]> = T["length"] extends 0 ? never : T[0];

빈 배열일 경우까지 예외처리를 추가한다.

Solution 1 : 조건문을 사용하여 만약 T가 빈 배열이라면 never를 반환하고, 빈 배열이 아니라면 T의 첫 번째 원소를 반환한다.

Solution 2 : infer 키워드를 사용해서 T의 원소에 접근해보았다.

Solution 3 : 배열로 한정된 T의 length 프로퍼티에 접근해 그 값이 0인지를 체크해 빈 배열임을 확인했다.

profile

jaenny.dev

@jaenny.dev

Go Beyond! Front-end developer, jaenny✨