타입스크립트 generic

세나정·2023년 3월 9일
0

TypeScript

목록 보기
3/6
post-thumbnail
이 공부는 HCC LAB의 정규 프론트엔드 스터디 중 종민님의 강연을 토대로 작성되었습니다!

타입과 값을 구분하자

  • TS로는 타입을 추가하는 것이지 값을 할당하는 것이 아님
  • Type Alias나 Interface는 타입을 정의하는 것이지 값을 정의하는 것이 아님
    -- 값을 넣는다는 것은 JS의 영역이고 우리는 "협업"을 위한 함수, 변수, 클래스의 스펙을 정의하는 작업을 TS로 할 뿐이다
    -- TS로 정의한 스펙 (매개변수 타입, 객체 타입, 리턴 타입 등)을 토대로 JS에 로직을 구현하는 것일 뿐

제네릭

제네릭을 알면 TS문법의 어려운 고비를 넘겼다고 생각할 정도로 생소하고 중요한 개념이니 확실히 잡고가자!

React의 대표적인 훅 useState의 타입을 정한다고 생각을 해보고
함수의 타입을 정할 때 고려사항은 두 가지
1. 매개변수의 타입은 무엇인지
2. 리턴 타입은 무엇인지

React-useState 예시 TS

우리가 useState를 사용하던 방법

const [ value, setValue ] = useState('a');
const [ value, setValue ] = useState('1');
const [ value, setValue ] = useState(true);

처럼 매개변수는 하나이고 리턴 값은 배열 (더 자세히는 튜플) 임을 알 수 있음
리턴 값이 배열인 이유는 우리는 배열로 리턴한 것을 비구조화 할당, destructuring을 한 JS의 문법을 사용했기 때문

리턴 값을 더 상세히 보자면 인자로 넣어준 state 값 (getter), state 값을 변경 해줄 수 있는 (setter) 함수로 고정되어 있음을 알 수 있음

만약 이러한 useState 구조를 타입스크립트에서 제네릭을 사용하지 않고 개발한다고 쳐보면 다음과 같은 형태가 나옴
더군다나 우리가 useState를 써봤듯 인자에는 객체와 배열 등이 들어갈 수 있음

그렇기에 완벽한 useState를 위해서는

이러한 코드로 작성을 해야하고 더군다나 React 라이브러리에는 useState만이 있는 것이 아닌 useContext, useReducer, useEffect 등 모든 React API를 저런 방식으로 일일이 구현을 해야하는 상황이 벌어짐

이렇게 번거로운 걸 제네릭을 사용하면 어떻게 되느냐하면

와우 이렇게 간단히 표현을 할 수가 있고
우린 더욱이 setState (setter 함수)를 더욱 가시성있게 보이게 하기 위해

이렇게 표현할 수 있다
이제 타입을 지정했으니 자바스크립트를 통해 로직을 직접 구현해보자면

이렇게 만들면 된다

여기서 <T>가 오른쪽에 붙은 건 전역, <T>가 왼쪽에 붙은 건 지역 이라고 여기면 됨
또한, 여기서 setState의 반환값이 void인 이유는 값을 변경해서 내보내는 것이 아닌 그저 타입을 적어주기 때문

만약 당신이 함수 타입을 상단부에 따로 지정하기 싫다면 함수와 타입을 한번에 쓰는 방법을 연습 해보면 됨

TS를 통해 개발을 한다는 것은 JS로 개발할 때는 차이점이 존재한다
JS로 개발을 할 때 로직을 먼저 생각하고 바로 구현을 했지만
TS는 타입을 먼저 구현하고 나서 개발에 들어가야만 함
즉, API 스펙을 먼저 다 지정하고 나서 로직을 구현해야만 함

이것이 처음엔 부담스럽고 귀찮게 다가오겠지만 현업, 협업에서 스펙을 정한다는 것은 매우 큰 장점

마지막으로, React에서는 useState 타이핑을 어떻게 했는가를 봅시다

실제 React useState

VS에서 Ctrl+클릭으로 d.ts 파일을 볼 수 있음

TS에서 제네릭에 대한 타입 추론?

파라미터를 반드시 필요로 함수에 인자로 값을 넣지 않은 경우
타입스크립트는 타입을 "모른다 (unKnown)"고 말을 함
이는 당연한 이야기임

제네릭은 타입을 함수나 클래스를 사용하는 사람이 지정하도록 (자유롭게) 하는 문법인데 타입을 넣어주지 않으니 타입스크립트 입장에서는 모르는 타입을 모른다고 할 뿐

그럼 위 함수에 한번 숫자를 넣어보면 어떨까요

우리는 4를 넣었음에도 얘는 text라고 말합니다
에? 왜 4지 라고 할 수 있겠지만
타입스크립트는 최대한 타입을 좁혀서 추론하려고 하는 특징이 있기 때문

const 변수에 넣은 값들을 해당 값에 해당하는 타입 리터럴로 추론 하듯이
우리도 함수 내부에서 콘솔로 찍고 해당 값을 바로 리턴하기 때문에 타입 리터럴ㄹ로 추론을 하게 되는 것 (text라고 했으니 믿고 찍고 다시 text로 반환)

그럼 T를 숫자로 추론하게 어떻게 할까욤

당연한 소리겠지만 제네릭을 갖다 치워주면 됨미다요

제네릭 대신 정말 명시적으로 number라고 쓰면 되지 않을까요

profile
압도적인 인풋을 넣는다면 불가능한 것은 없다. 🔥

0개의 댓글