타입스크립트 챌린지 1주차 학습 회고

리버 river·2024년 8월 12일
0

학습 회고

목록 보기
1/4
post-thumbnail

타입스크립트에 빠지다

타입스크립트때문에 고생한 기억이 많습니다.

나는 분명히 다 타입 지정해줬는ㄷ...

걸핏하면 해당 타입을 할당할 수 없다는 에러를 마주했죠. 타입스크립트의 유용성 보다는 타입 체크에 지쳐가는 개발 생활을 했던것 같습니다. 타입스크립트 공부해야지 해야지 하고만 있다가, 몇 주 전에 리액트 마이크로 상태관리라는 책을 5장까지 정독하며 개발서적의 참맛을 느끼는 경험을 하게되었습니다. 이 후로 또 재밌는 개발 서적 없나? 하는 참에 앞서 말해드린 타입스크립트 공부에 대한 수요와 맞물려 우아한 리액트 타입스크립트라는 책으로 정하게 된것입니다.

이 책(이하 우리타라고 줄이겠습니다.)을 보면서 타입스크립트에 대한 흥미가 높아졌습니다. 일단 에러 예시들이 상당수가 제가 다 마주했던 에러들이라 개발 서적인데도 맞아 맞아 하면서 더 몰입해서 읽을 수 있었습니다.

이렇게 우리타 4장까지 보고 나니깐
"아 나 이제 타입스크립트 알겠다 (?)" 라는 지경까지 갔습니다. (심지어 타입스크립트 학습 부분이 4장이 끝이 아닌데도..) 사실 제네릭을 순수 제 힘으로 사용해서 추상화해본 경험이 없었는데 이 책을 읽고나서 처음으로 이번 우테코 레벨3 프로젝트에서 테이블 컴포넌트를 추상화하는 부분에 제 힘으로 제네릭을 성공적으로 써본것이 처음이라 고양감에 더 그랬던것 같습니다. 😅

나는 이제 타잘알이 된 줄 알았지..

이 도파민을 계속 이어나가기위해 더 할 수있는것이 없을까? 라고 생각하다가 예전에 어떤 크루가 알려준 타입스크립트 챌린지가 생각 났습니다.

들어가보니 쉬움부터 난이도 별로 문제가 잘 정리되어있어서 지금의 저에게 딱이구나 싶었습니다.

제네릭도 쓸 줄 아는 나(?)지만 쉬움 레벨부터 풀어주지 라는 생각으로 기세등등하게 문제를 보는데.. 든 생각은

이거 쉬움 맞아??

바로 겸손해지며 쉬움 첫 문제부터 차근차근 헤쳐나가기 시작했습니다...

기억이 나는 것과 이해는 다르다

쉬움 문제를 풀며 4장 이후의 내용인 extends 조건부 타입,infer 등 추가적인 학습을 이어 나가니 4장까지만 읽고나서 문제를 마주쳤을 때 보다는 확실히 체감 난이도가 낮아지는것을 느낄 수 있었습니다.

그러함에도 불구하고 정말 이게 쉬움 맞아 정말로? 라고 느꼈던 문제가 있었는데요

타입스크립트 챌린지 | 쉬움 난이도 | Includes<>

Includes<>를 Include를 사용하지 않고 구현하는 문제입니다.
골머리를 썩다가 결국 답안를 보았는데, 답안를 봐도 이해하기 힘들더라구요. 풀이를 보니 이미 타입스크립트를 정말 잘 아시는 분이 이렇게 짧게 풀 수도있다라는 느낌으로 작성된 답안이었습니다. 지금 제 수준에는 맞지 않다고 느껴 더 정석적인 답안이 필요하다 생각해서 클로드에게 물어봤는데 제가 딱 원하는 느낌의 답안이 나왔습니다.

type Includes<T extends readonly any[], U> = T extends [infer First, ...infer Rest]
  ? Equal<First, U> extends true
    ? true
    : Includes<Rest, U>
  : false;

바로 위 코드입니다. 첫 원소부터 돌아가면서 확인하는 풀이인데 굉장히 합리적이라 생각했습니다.

이해했다고 생각했고, 다시 문제를 풀어봤을 때도 똑같이 적었기에 제가 이 문제는 이제 제가 이해했고, 또 풀 줄도 아는 문제라고 생각하고 넘어갔습니다.

이틀 후 이 문제가 다시 생각나서 다시 풀어볼려했는데 웬걸

T extends [infer First, ...infer Rest]

이 첫 부분부터 못적고 있는 저를 발견했습니다.
이유는 단순합니다. 제가 infer를 잘 모르고 있었기 때문입니다.

분명 우리타 책에도 infer는

extends로 조건을 서술하고 infer로 타입을 추론하는 방식을 취한다.

라고 잘 적혀있고 형광펜도 쳐놨습니다.

하지만 정작 제 머리속에 각인된것은?

type UnpackPromise<T> = T extends Promise<infer K>[] ? K : any;

인거죠. 이 예시가 저 설명에 대한 하나의 예시로 머리속에 들어온게 아니라, 굉장히 편협적으로 아 제네릭 안에 infer 쓰는구나라고만 머리에 박힌거죠.

infer에 대한 이해가 이렇게 되어있으니
T extends [infer First, ...infer Rest]라는 부분을 당장 답안에 대한 단기 기억력이 남아있을 때만 바로 적어낼 수 있었고 하루가 지나니 바로 기억나지 않은거죠.

사실 처음 저 코드를 봤을 때부터 저런 이유로 굉장히 생소하게 느껴졌지만 일단 많이 풀고 봐야겠다는 심정에 대충 넘어간것같습니다.

이틀 후 바로 리셋된 제 기억력에 충격받고 클로드에게 아래와 같은 질문을 하게됩니다..

여기서 또 발견한 제 문제..
보시면 아시겠지만 정확한 용어를 모르는 상태입니다.
타입 변수라는 말도 굉장히 애매모호한 상태에서 사용한 단어입니다.
이런 상태야말로 그 개념을 잘 모르고있다라는 확실한 지표 중 하나라고 생각합니다.


확실히 하기위해 다시 이런 질문을 했습니다.

네, 질문을 개발 용어를 사용하여 더 정확하고 깔끔하게 재구성해 드리겠습니다:
"조건부 타입의 extends 절 내에서 infer 키워드를 사용할 때, 추론된 타입 변수를 선언하는 위치에 제한이 있나요? 예를 들어, T extends [infer First, ...infer Rest]와 같은 구문에서 infer로 선언된 타입 변수들(First와 Rest)은 배열 또는 튜플 타입의 요소 위치에 자유롭게 배치될 수 있는 건가요? 이러한 infer 키워드의 사용 패턴이 TypeScript의 타입 시스템에서 일반적으로 허용되는 문법인가요?"
이렇게 재구성된 질문은 다음과 같은 핵심 개념들을 포함합니다:

  • 조건부 타입 (Conditional Types)
  • extends 절 (extends clause)
  • infer 키워드 (infer keyword)
  • 추론된 타입 변수 (Inferred Type Variables)
  • 배열 및 튜플 타입 (Array and Tuple Types)

이를 통해 TypeScript의 고급 타입 시스템에 대한 이해를 더 명확히 표현할 수 있습니다.

굉장히 만족스러운 답변이 나왔습니다.

위 답변으로 제가 위에서 표현한 '제네릭 안에서만 쓸 수 있는 줄 알았다' 라는 표현도 뭔가 정확한 표현이 아니라는것을 알 수 있죠

다시 명확하게 표현해보겠습니다

나는 infer를 제네릭 타입 선언 안에서만 사용할 수 있는 줄 알았는데, 타입 변수들 앞에서 사용되어 그 타입 변수를 추론하는데 사용할 수 있다.

메타인지를 위한 액션플랜 추려보기

위와 같은 경험으로 앞으로의 학습에서 메타인지를 높이기 위해 취해야할 액션 플랜 몇 개를 뽑아봤습니다.

  1. 타입스크립트 챌린지처럼 코딩 문제를 풀게 될 경우, 답안을 보고나서 고대로 다시 적어냈다고 이해했다고 착각하지 말기.

  2. 개발 용어를 정확하게 머리 속에 넣자.

  3. 애매모호한 용어 사용으로 질문을 하게 될 경우 내 질문을 정확한 개발용어를 사용해서 수정해달라고 요구하기.

마무리

타입스크립트 챌린지 1주차는 일단 이정도로 마무리됐습니다.
1주차에서 일단 쉬움 난이도는 다 풀긴풀었는데, 이번 글에서 다룬 Includes 문제뿐만 아니라 다른 문제에서도 위와 같은 이슈가 분명이 있으거라 생각됩니다.

쉬움 난이도 문제들이긴하지만, 우리타 5장까지 다룬 개념들의 다반수가 다뤄졌습니다. 그렇기에 이번 주는 바로 다음 단계인 보통 난이도로 가지않고, 이번 학습 회고글에서 새운 액션 플랜을 지키며 모든 문제를 다시 복습해 보겠습니다.

레벨3 프로젝트의 마지막 4차 데모데이를 앞두고 굉장히 바쁠것이지만, 또 마음 급하다고 대충하지 말고 최대한 메타인지를 발휘해보아야겠습니다

profile
프론트엔드 개발자

0개의 댓글

관련 채용 정보