iamkanguk.dev

[타입챌린지 - EASY] 14 - First of Array 본문

Type Challenge

[타입챌린지 - EASY] 14 - First of Array

iamkanguk 2024. 3. 10. 17:36

문제

https://github.com/type-challenges/type-challenges/blob/main/questions/00014-easy-first/README.md

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

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

 

풀이

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

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

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

 

How to Solve?

먼저, 문제에서 배열타입을 다루기 때문에 제네릭 T가 배열 타입이라는 것을 명시해줘야 해서 extends any[]를 설정해주어야 한다.

우리는 첫 번째 원소에 접근을 해야하니까 T[0]으로만 하면 되는 줄 알았더니, 빈 배열에 대한 예외처리가 불가능하기 때문에 추가 수정이 필요하다.

 

그래서 우리는 빈 배열인 경우 never, 그렇지 않은 경우에는 T의 첫 번째 원소인 T[0]을 반환하면 된다.

 

Solution 1 (필자의 가장 근접한 접근방법)

T가 빈 배열인 경우 never를 반환하고 빈 배열이 아니면 첫 번째 원소를 반환하게 코드를 작성했다. extends를 통해 T가 빈 배열이라고 명시를 하는 것이 중요하다.

Solution 2

T["length"] 를 통해 T 배열의 길이가 0인지 아닌지 확인해서 그에 맞는 값을 Return 해준다.

Solution 3 (필자에게 생소함)

infer 키워드를 사용해서 구현할 수 있다. 그리고 spread operator를 통해서 첫 번째 원소와 나머지 원소들을 분리하는데 이 때 첫 번째 원소 부분에 infer 키워드를 통해 추론 가능한 값이면 첫 번째 원소(U)를 바로 반환하고 그렇지 않은 경우에는 never를 반환한다.

 

새로 알게된 점

infer

infer에 대해서는 해당 링크에서 아주아주 잘 설명되어 있다. 참고하면 좋을 것 같다 :)

 

후기

빈 배열인지 어떻게 확인하지?  라는 고민을 계속했던 것 같다. 결국에는 풀지 못하긴 했지만 그래도 위의 방법으로 빈 배열임을 확인할 수 있다는 것을 알게 되었다. 생각보다 어렵지는 않았던 문제인 것 같다


- https://jaenny-dev.tistory.com/2

 

[타입챌린지/type-challenge] First of Array

문제 배열 타입 T를 받아 그 배열의 첫 번째 원소의 타입을 리턴하는 제네릭 First를 구현하세요. type arr1 = ['a', 'b', 'c'] type arr2 = [3, 2, 1] type head1 = First // expected to be 'a' type head2 = First // expected to be 3

jaenny-dev.tistory.com

- https://velog.io/@from_numpy/TypeScript-infer

 

TypeScript - infer

조건부 타입의 조건식이 참으로 평가될 때에는 infer키워드를 사용할 수 있다. 예를 들어,Element<number> extends Element<infer U>와 같은 타입을 작성하면, U타입은 number타입으로 추론(infer)된다. 이후, 참

velog.io