diff --git "a/\353\260\225\354\212\271\355\233\210/220729.md" "b/\353\260\225\354\212\271\355\233\210/220729.md"
new file mode 100644
index 0000000..fb9d294
--- /dev/null
+++ "b/\353\260\225\354\212\271\355\233\210/220729.md"
@@ -0,0 +1,347 @@
+# TypeScript 고급
+
+
+
+## 제네릭(Generics)
+
+### 제네릭이란?
+
+> 재사용성이 높은 컴포넌트를 만들 때 자주 활용되는 특징
+
+**한 가지 타입보다 여러 가지 타입에서 동작하는 컴포넌트 생성에 사용**
+
+
+
+```js
+// JavaScript
+function logText(text) {
+ console.log(text);
+ return text;
+}
+
+logText('Hello');
+logText(10);
+logText(true);
+```
+
+- JS 문법의 경우 위와 같은 함수에서는 어떤 것이든 인자로 사용 가능
+
+
+
+```ts
+// TypeScript
+function logText(text: T): T {
+ console.log(text);
+ return text;
+}
+
+logText('Hello');
+```
+
+- TS의 generic을 활용하면 **함수를 호출할 때 type을 정의하겠다**는 약속
+- 함수를 추상화해서 더 다양한 type에서 사용 가능
+
+
+
+![image](https://user-images.githubusercontent.com/86189596/173964717-a4c8de60-89e0-4b87-86ec-4c0109d70768.png)
+
+- 함수 호출에서 type을 정의하면 해당하는 type의 전달과 출력이 type으로 지정
+
+
+
+### 기존 TS 함수의 중복 선언
+
+```js
+function logText(text: string) {
+ console.log(text);
+ return text;
+}
+
+function logNumber(num: number) {
+ console.log(num);
+ return num;
+}
+
+logText('a')
+logNumber(10)
+```
+
+- 기존 TS 문법은 type에 따라 함수를 중복 정의 해야한다.
+- 유지보수 차원에서 좋지 않음
+
+
+
+### 유니온 타입을 이용한 선언 방식 문제점
+
+```ts
+function logText(text: string | number) {
+ console.log(text);
+ return text;
+}
+```
+
+> 문제점1. 지정된 여러 type이 공통으로 가지는 method에서만 preview 지원
+
+![image](https://user-images.githubusercontent.com/86189596/173974315-b5d3e702-f8a2-4973-9cb6-a3deecd59a2f.png)
+
+
+
+> 문제점2. 한 가지 타입에서만 존재하는 메서드 사용 불가
+
+![image](https://user-images.githubusercontent.com/86189596/173974478-986beeef-1030-488e-9c90-277e99a356d1.png)
+
+- 해당 함수의 결과값은 union type이므로 한 가지 type에서만 지원하는 메서드 사용 불가
+
+
+
+### 제네릭의 장점과 타입 추론에서의 이점
+
+```ts
+function logText(text: T): T {
+ console.log(text);
+ return text;
+}
+
+const str = logText('a')
+str.split('')
+
+const num = logText(10)
+num.toLocaleString()
+```
+
+- generic을 통한 type 정의를 통해 return된 값을 변수로 지정
+- 이 변수는 각 type에서 지원하는 method 사용 가능
+
+![image](https://user-images.githubusercontent.com/86189596/174127271-80278ded-b588-43da-9279-1f610984da11.png)
+
+
+
+### 인터페이스에 제네릭 선언
+
+```ts
+interface Dropdown {
+ value: T;
+ selected: boolean;
+}
+
+const obj1: Dropdown = { value: 'abc', selected: false };
+const obj2: Dropdown = { value: 10, selected: false };
+```
+
+
+
+### 제네릭의 타입 제한
+
+```ts
+function logTextLength(text: T): T {
+ console.log(text.length);
+ return text;
+}
+
+logTextLength('hi');
+```
+
+- 함수 내부에서 인자의 메서드 사용은 인자의 type마다 다르다.
+- generic에서 type은 호출 때 정의되므로, 함수 작성 시에는 오류 발생
+
+![image](https://user-images.githubusercontent.com/86189596/174138959-ca4af74a-ed1e-423a-a748-374fb2e61ac4.png)
+
+
+
+> 힌트를 주자!
+
+- text는 length를 셀 수 있는 애라는 것을 알린다!
+- text는 배열이라고 가정
+
+```ts
+function logTextLength(text: T[]): T[] {
+ console.log(text.length);
+ text.forEach(function (text) {
+ console.log(text);
+ })
+ return text;
+}
+
+logTextLength(['hi', 'abc']);
+```
+
+- 실제 인자도 Array 형태로 전달해야 한다.
+
+
+
+### 제네릭의 타입 제한2 : 정의된 타입 이용
+
+```ts
+interface LengthType {
+ length: number;
+}
+
+function logTextLength(text: T): T {
+ text.length;
+ return text;
+}
+
+logTextLength('abcdef');
+logTextLength(['a', 'b', 'c', 'd'])
+logTextLength({ length: 10 })
+logTextLength(10);
+```
+
+- 정의될 Type은 length 속성/메서드를 가진 LengthType의 상속을 받는 type이 된다.
+- T type은 LengthType에 추가로 정의
+
+![image](https://user-images.githubusercontent.com/86189596/174140574-08be9372-f30c-4fd0-9803-624eca70aeb1.png)
+
+
+
+### 제네릭의 타입 제한3 : keyof 이용
+
+```ts
+interface ShoppingItem {
+ name: string;
+ price: number;
+ stock: number;
+}
+
+function getShoppingItemOption(itemOption: T): T {
+ return itemOption;
+}
+getShoppingItemOption('name');
+```
+
+interface의 key들 중 하나를 인자로 사용
+
+
+
+## Promise를 이용한 API 함수 타입 정의
+
+```ts
+function fetchItems(): Promise {
+ let items = ['a', 'b', 'c'];
+ return new Promise(function (resolve) {
+ resolve(items);
+ })
+}
+fetchItems();
+```
+
+
+
+## enum을 이용한 타입 정의
+
+```ts
+findContactByPhone(phoneNumber: number, phoneType: string): Contact[] {
+ return this.contacts.filter(
+ contact => contact.phones[phoneType].num === phoneNumber
+ );
+}
+```
+
+
+
+
+이런 함수의 경우 인자로 phoneType을 받는다.
+
+```ts
+findContactByPhone('Homee');
+```
+
+그런데 이런 경우 오타를 방지할 수 없기 때문에 아래와 같이 enum을 사용
+
+
+
+```ts
+enum PhoneType {
+ Home = 'home',
+ Office = 'office',
+ Studio = 'studio',
+}
+```
+
+```ts
+findContactByPhone(PhoneType.Home);
+```
+
+오타에 대한 에러를 바로 확인 가능
+
+
+
+## 타입 추론(Type Inference)
+
+### 타입 추론이란?
+
+```ts
+// parameter의 type으로 return 값의 type이 결정
+function getB(b) {
+ return b;
+}
+```
+
+```ts
+// parameter의 type으로 return 값의 type이 결정
+function getB(b) {
+ const c = 'hi'
+ return b + c;
+}
+```
+
+- number + string = string으로 type 추론
+- return 값이 내부적으로 string으로 추론
+
+
+
+### 인터페이스와 제네릭에서의 타입 추론
+
+> 인터페이스와 제네릭
+
+```ts
+interface Dropdown {
+ value: T;
+ title: string;
+}
+
+const shoppingItem: Dropdown = {
+ value: 'abc',
+ title: 'hello',
+}
+```
+
+
+
+> 인터페이스의 상속
+
+```ts
+interface Dropdown {
+ value: T;
+ title: string;
+}
+
+// 관행적으로 T를 쓰지만 구분을 위해 K 사용
+interface DetailedDropdown extends Dropdown {
+ description: string
+ tag: K;
+}
+
+const detailedItem: DetailedDropdown = {
+ value: 'abc',
+ title: 'hello',
+ description: '안녕하세요~~',
+ tag: 'a'
+}
+```
+
+인터페이스 A를 상속받은 인터페이스 B는 generic의 Type도 상속 가능
+
+
+
+### Best Common Type
+
+> 배열 내에 type이 여러 종류가 있는 경우
+
+```ts
+const arr: (number | string | boolean)[] = [1, 2, 3, 'a', 'b', 'c', true];
+```
+
+유니온 타입을 이용해 배열에 들어간 개체들의 타입을 추론해 union type으로 정의
+
+![image](https://user-images.githubusercontent.com/86189596/174268126-33d74c33-0a86-45fc-919e-3d08201a55fc.png)
\ No newline at end of file