---
description: https://github.com/OneMoreBottlee/TypeScript-Master/tree/main/S14
---

# \[S14] Generics ⭐⭐⭐⭐⭐

매우 중요한 개념 but 복잡하다

까다로운 개념과 구문으로 혼란…

**Generics**

Generics allow us to define reusable functions and classes that work with multiple types rather than a single type.

TS의 여러 타입에서 사용할 수 있는 재사용 함수나 재사용 클래스를 정의할 수 있게 해주는 특수 기능



**사용 예시 1**

< 이곳 > 이곳에 원하는 타입을 넣어 사용할 수 있다.

```tsx
const num : number[] = []
const nums: Array<number> = []
const colors: Array<string> = []
```

DOM 을 다룰때

```tsx
const inputEl = document.querySelector<HTMLInputElement>("#username")!
console.log(inputEl.value)

inputEl.value = "Howw"

const btn = document.querySelector<HTMLButtonElement>(".btn")!
console.log(btn)
```



**첫 번째 제네릭 작성하기**

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FPxC3pz7v3tfPxrhRJYWg%2Fimage.png?alt=media&#x26;token=00aee504-e141-4631-b802-80d4209007ce" alt=""><figcaption></figcaption></figure>

숫자를 넣으면 숫자가, 문자를 넣으면 문자가, 불리언을 넣으면 불리언이

입력한 타입 값 그대로 출력되는 함수가 있다고 해보자.

위와 같이 각 타입별로 하나씩 입력하거나

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FU38Eh0TwkYlg0PmJ3Yfy%2Fimage.png?alt=media&#x26;token=055fd6dd-2de3-43db-9d3b-179bf67e489e" alt=""><figcaption></figcaption></figure>

any 로 처리 해야된다.

하지만 첫번째 방법은 비효율적이고, 두번째 방법은 타입스크립트의 취지와 맞지 않다.

이러한 상황에서 제너릭을 사용한다.

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FtSCHmENCsYHkGghea4L1%2Fimage.png?alt=media&#x26;token=77708c89-dfee-4505-8580-c70b89211a92" alt=""><figcaption></figcaption></figure>

입력하는 타입과 출력하는 타입이 같다.

숫자는 숫자, 문자열은 문자열, 불리언은 불리언.

이렇게 제네릭이 여러가지 타입을 받을 수 있도록 반환한다.



**제네릭 함수**

함수에서도 위와 같이 설정할 수 있다.

입력값의 타입이 확실하지 않을때 제너릭을 사용한다.

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2F3eZws9J7VQ9QyXtdvUXN%2Fimage.png?alt=media&#x26;token=67ee57c0-b829-435c-a3ee-ff781c914683" alt=""><figcaption></figcaption></figure>

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2F3uyWcrejMWsVwDB3u7rq%2Fimage.png?alt=media&#x26;token=79c67e9b-e0fc-4f61-80d6-ff576c1d3cbc" alt=""><figcaption></figcaption></figure>



**추론된 제너릭 타입 파라미터**

타입스크립트는 추론으로 타입을 확인할 수 있기에 위와 같이 타입 값을 일일이 넣지 않아도 된다.

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FKVm2he2f1KerFGAcMoPM%2Fimage.png?alt=media&#x26;token=02f183f5-6106-41d8-85d1-8ed576404f98" alt=""><figcaption></figcaption></figure>

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FV42vN3PygpRI1UGECqGX%2Fimage.png?alt=media&#x26;token=27b04184-0412-4043-9390-d34d3482f25c" alt=""><figcaption></figcaption></figure>

입력값이 명확하다면 타입스크립트의 추론을 믿고, 불분명하다면 제너릭을 넣는게 좋다.



**제너릭, 화살표 함수 및 TSX 파일**

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2F7OyJQOHotWQ2HcocC1oe%2Fimage.png?alt=media&#x26;token=e10ac1d0-6983-4525-8ec7-1eadb259f0c6" alt=""><figcaption></figcaption></figure>

React, TS, 화살표 함수를 사용한다면 , 를 기억하자



**여러 타입을 가진 제너릭**

타입이 여러개인 제너릭이 필요한 경우 다음과 같이 설정한다.

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FKROb7UAPGTBDPIAuW7sU%2Fimage.png?alt=media&#x26;token=46b44f29-a428-4f90-86f8-857c2b21ed85" alt=""><figcaption></figcaption></figure>

예) 두 객체를 합치는 함수

T, U 를 하나의 제너릭에 넣고 분배

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FTZzOJAT61Pf0YAYko024%2Fimage.png?alt=media&#x26;token=228d66f2-8c86-4770-98e9-575f0ec4f5f9" alt=""><figcaption></figcaption></figure>



**타입 제한 추가하기**

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2F0hd2JXY5wA1vO5i6X1Q0%2Fimage.png?alt=media&#x26;token=7c187ca8-a56c-4dc3-a0bc-05592c44f49b" alt=""><figcaption></figcaption></figure>

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FAgIAiSQ9u6dK64axr1NN%2Fimage.png?alt=media&#x26;token=ee529789-0fa4-4861-ae72-9259847db4f8" alt=""><figcaption></figcaption></figure>

제너릭을 사용할 때 원하지 않는 타입이 들어가는 경우도 있다.

그러면 위와 같이 에러없이 작동하고 원하지 않는 결과가 탄생한다.

이런 일을 방지하고자 타입을 제한할 수 있다.

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FlTx7Mc189qpYqihRqLBc%2Fimage.png?alt=media&#x26;token=5050d353-37f3-431c-9b95-6b070f7d753a" alt=""><figcaption></figcaption></figure>

extends 타입 을 추가하면서 에러가 발생하게 된다.

조건에 인터페이스를 추가할 수 도 있다.

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2Fy4Q4kfNRWNUmcRJaOEYM%2Fimage.png?alt=media&#x26;token=d3059a40-03b1-46c6-9318-7db955f0b99a" alt=""><figcaption></figcaption></figure>



length 가 없기에 인터페이스를 추가한다.

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FEnUBHH9Dqgsdr62OR2Ry%2Fimage.png?alt=media&#x26;token=bce4334d-397d-467f-a8bb-b8e9ac8ac39a" alt=""><figcaption></figcaption></figure>

에러가 사라진다.



**기본 타입 파라미터**

타입 파라미터에 기본값을 설정할 수 있다.

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FbkndxCPvPLD4ujcjLR3i%2Fimage.png?alt=media&#x26;token=f5cb5954-8e0d-483f-b761-45e8cbcada95" alt=""><figcaption></figcaption></figure>

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FLL9oe4A7CPgAVml0wftT%2Fimage.png?alt=media&#x26;token=caf40c7d-b6e0-4afb-a7a9-cbd7e413e47a" alt=""><figcaption></figcaption></figure>

\<T = number> 로 기본값이 설정됨

\<string>을 추가하면 string 타입이 됨



**Class**

제너릭을 사용해 클래스를 만들 수 있다.

<figure><img src="https://534473029-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fh5bANRFbqQiBiOjIxpbm%2Fuploads%2FUFH3PrOwjhlp4syhXEgV%2Fimage.png?alt=media&#x26;token=a46da0d5-3941-4df1-bdee-8df4293e5526" alt=""><figcaption></figcaption></figure>
