diff --git "a/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.1_\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\353\237\260\355\203\200\354\236\204\352\263\274_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\354\273\264\355\214\214\354\235\274/seulgi.md" "b/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.1_\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\353\237\260\355\203\200\354\236\204\352\263\274_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\354\273\264\355\214\214\354\235\274/seulgi.md"
index 3beced8..e498801 100644
--- "a/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.1_\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\353\237\260\355\203\200\354\236\204\352\263\274_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\354\273\264\355\214\214\354\235\274/seulgi.md"
+++ "b/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.1_\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\353\237\260\355\203\200\354\236\204\352\263\274_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\354\273\264\355\214\214\354\235\274/seulgi.md"
@@ -1 +1,79 @@
-
+# 1. 자바스크립트의 런타임과 타입스크립트의 컴파일
+
+## 1) 런타임과 컴파일타임
+
+프로그래밍 언어는 일반적으로 고수준 언어 / 저수준 언어로 구분할 수 있다.
+
+
+
+### 고수준 언어? 저수준 언어?
+
+- 고수준 언어 : 사람이 이해하기 쉬운 형식으로 작성
+- 저수준 언어 : 컴퓨터가 이해하기 쉬운 형식으로 작성
+
+자바스크립트는 대표적인 고수준 언어로, 컴파일러나 인터프리터에 의해
+저수준 프로그래밍 언어, 즉 기계가 이해할 수 있는 언어로 번역되어 실행된다.
+
+### 컴파일 타임?
+
+소스코드(개발자가 작성)가 컴파일 과정을 거쳐 컴퓨터가 인식할 수 있는
+기계어 코드(바이트 코드)로 변환되어 실행할 수 있는 프로그램이 되는 과정이다.
+
+### 런타임?
+
+소스코드의 컴파일이 완료되면 프로그램이 메모리에 적재되어 실행되는데
+이 시간을 런타임이라고 하는데 즉 런타임은 컴파일 과정을 마친 응용 프로그램이
+사용자에 의해 실행되는 과정이다.
+
+
+
+
+## 2) 자바스크립트 런타임
+
+자바스크립트 런타임은 자바스크립트가 실행되는 환경이다.
+
+자바스크립트 런타임의 주요 구성 요소로
+자바스크립트 엔진, 웹 API, 콜백 큐, 이벤트 루프, 렌더 큐가 있다.
+
+> 자바스크립트는 대표적인 인터프리터 언어로 별도의 컴파일 과정이 존재하지 않는다고 알려져 있다.
+
+> 하지만 엄밀히 말해 컴파일 단계가 존재하는데 자바스크립트를 해석하고 실행하는 역할을 하는
+> V8 엔진은 때때로 자바스크립트 코드를 최적화하기 위해 컴파일 단계를 거친다.(실행 속도 향상을 위한 목적)
+> 이 과정에서 자바스크립트 코드를 캐싱해 실행 시간을 단축시킨다.
+
+
+
+
+## 3) 타입스크립트의 컴파일
+
+타입스크립트는 **tsc**라고 불리는 컴파일러를 통해 자바스크립트 코드로 변환된다.
+
+하지만, 타입스크립트는 고수준언어 -> 고수준 언어로 변환되는 것이기 때문에
+컴파일이 아닌 트랜스파일로 불리거나 소스코드 -> 다른 소스코드로 변환하는 것이기에
+소스 대 소스 컴파일러라고 지칭하기도 한다.
+
+> 타입스크립트 컴파일러는 소스코드를 해석해 AST를 만들고 이후 타입 확인을 거친 다음 결과 코드를 생성한다.
+
+
+
+### 컴파일러가 소스코드를 컴파일해 프로그램으로 실행되기까지의 과정을 알아보자!
+
+1. 타입스크립트 소스코드를 타입스크립트 AST로 만든다.(tsc)
+2. 타입 검사기가 AST를 확인해 타입을 확인한다.(tsc)
+3. 타입스크립트 AST를 자바스크립트 소스로 변환한다.(tsc)
+4. 자바스크립트 소스코드를 자바스크립트 AST로 만든다.(런타임)
+5. AST가 바이트 코드로 변환된다.(런타임)
+6. 런타임에서 바이트 코드가 평가되 프로그램이 실행된다.(런타임)
+
+### AST(Abstract Syntax Tree)?
+
+컴파일러가 소스코드를 해석하는 과정에서 생성된 데이터 구조다.
+컴파일러는 어휘적 분석과 구문 분석을 통해 소스코드를 노드 단위의 트리 구조로 구성한다.
+
+### 타입스크립트 === 정적 검사기?
+
+타입스크립트를 컴파일타임에 에러를 발견할 수 있는 정적 검사기라고 부르는데
+컴파일타임에 타입을 검사하기 때문이다.(런타임 전 에러 발견 가능)
+
+
+
diff --git "a/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.2_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274\353\237\254\354\235\230_\353\217\231\354\236\221/seulgi.md" "b/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.2_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274\353\237\254\354\235\230_\353\217\231\354\236\221/seulgi.md"
index 3beced8..46f1cb0 100644
--- "a/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.2_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274\353\237\254\354\235\230_\353\217\231\354\236\221/seulgi.md"
+++ "b/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.2_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274\353\237\254\354\235\230_\353\217\231\354\236\221/seulgi.md"
@@ -1 +1,94 @@
-
+# 2. 타입스크립트 컴파일러의 동작
+
+## 1) 코드 검사기로서의 타입스크립트 컴파일러
+
+타입스크립트는 컴파일타임에 문법 에러와 타입 관련 에러를 모두 검출한다.
+
+```js
+const developer = {
+ work() {
+ console.log("working");
+ },
+};
+
+developer.work();
+developer.sleep(); // TypeError;
+```
+
+> 해당 코드를 자바스크립트로 작성하는 시점에는 에러가 발생하지 않으나, 실제 실행 시 에러가 난다.
+
+```ts
+const developer = {
+ work() {
+ console.log("working");
+ },
+};
+
+developer.work();
+developer.sleep(); // Property "sleep" does not exist on type "{work(): void}"
+```
+
+> 타입스크립트는 코드를 실행 전에 에러를 사전에 발견해 알려준다.
+> 즉, 런타임에 발생할 수 있는 문법 오류 등의 에러뿐 아니라 타입 에러도 잡을 수 있다.
+
+타입스크립트 컴파일러는 tsc binder를 사용하여 타입 검사를 하며, 컴파일타임에 타입 오류를 발견한다.
+타입 검사를 거쳐 코드를 안전하게 만든 이후에는 타입스크립트 AST를 자바스크립트 코드로 변환한다.
+
+
+
+
+## 2) 코드 변환가로서의 타입스크립트 컴파일러
+
+타입스크립트 코드를 각자의 런타임 환경에서 동작할 수 있도록
+구버전의 자바스크립트로 트랜스파일한다.
+이것이 타입스크립트 컴파일러의 두 번째 역할이다.
+
+- 타입스크립트 컴파일러의 target 옵션을 사용하여 특정 버전의 자바스크립트 소스코드로 컴파일할 수 있다.
+- 타입스크립트 컴파일러는 타입 검사를 수행한 후 코드 변환을 시작한다.
+- 이때 타입 오류가 있더라도 일단 컴파일을 진행한다.
+
+> 타입스크립트 코드가 자바스크립트 코드로 변환되는 과정은
+> 타입 검사와 독립적으로 동작하기 때문이다.
+
+> 타입스크립트 코드 타이핑이 잘못되서 발생하는 에러도 런타임 에러로 처리된다. 자바스크립트 실행 과정에서 런타임 에러로 처리된다.
+
+### 다만 문제가 있다..!
+
+타입스크립트 소스코드에 타입 에러가 있더라도
+자바스크립트로 컴파일되어 타입 정보가 모두 제거된 후에는
+타입이 아무런 효력을 발휘하지 못한다.
+
+```ts
+interface Square {
+ width: number;
+}
+
+interface Rectangle extends Square {
+ height: number;
+}
+
+type Shape = Square | Rectangle;
+
+function calculateArea(shape: Shape) {
+ // 에러! Rectangle이 타입이기 때문에 런타임은 해당 코드를 이해하지 못함
+ if (shape instanceof Rectangle) {
+ return shape.width * shape.height;
+ } else {
+ return shape.width * shape.width;
+ }
+}
+```
+
+> 타입스크립트 코드가 자바스크립트로 컴파일되는 과정에서 모든 인터페이스, 타입, 타입 구문이 제거되어 버리기 때문에 런타임에서는 타입을 사용할 수 없다.
+
+### 타입스크립트 컴파일러의 역할?
+
+1. 최신 버전의 타입스크립트 / 자바스크립트 코드를 구버전의 자바스크립트로 트랜스파일한다.
+2. 코드의 타입 오류를 검사한다.
+
+### 바벨 (Babel)?
+
+ECMAScript 2015 이후의 코드를 현재 또는 오래된 브라우저와 호환되는 버전으로 변환해주는 자바스크립트 컴파일러이다.
+
+
+
diff --git "a/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.3_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274\353\237\254\354\235\230_\352\265\254\354\241\260/seulgi.md" "b/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.3_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274\353\237\254\354\235\230_\352\265\254\354\241\260/seulgi.md"
index 3beced8..b91a80a 100644
--- "a/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.3_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274\353\237\254\354\235\230_\352\265\254\354\241\260/seulgi.md"
+++ "b/CH06_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274/6.3_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270_\354\273\264\355\214\214\354\235\274\353\237\254\354\235\230_\352\265\254\354\241\260/seulgi.md"
@@ -1 +1,184 @@
-
+# 3. 타입스크립트 컴파일러의 구조
+
+타입스크립트 컴파일러가 동작하는 데 중요한 몇 가지 중요한 구성 요소가 있다.
+타입스크립트 컴파일러의 구체적인 동작을 살펴보자.
+
+| 순서 | 단계 | 설명 |
+| ---- | ------ | ----------------------------- |
+| 1 | 스캐너 | .ts 토큰화 |
+| 2 | 파서 | 토큰 기반 AST 생성 |
+| 3 | 바인더 | AST 노드 기반 심볼 생성 |
+| 4 | 체커 | AST + 심볼 기반 타입 검사 |
+| 5 | 이미터 | AST + 코드 생성 기반 .js 생성 |
+
+> 위의 5단계를 거쳐 타입 검사와 자바스크립트 소스 변환을 진행한다.
+
+
+
+
+## 1) 프로그램(Program)
+
+타입스크립트 컴파일러는 tsc명령어로 실행된다.
+컴파일러는 tsconfig.json에 명시된 컴파일 옵션을 기반으로 컴파일을 수행한다.
+
+전체적인 컴파일 과정을 관리하는 프로그램 객체(인스턴스)가 생성되고,
+객체 내 컴파일할 타입스크립트 소스 파일과 소스 파일 내 임포트된 파일을 불러오는데
+가장 최초 불러온 파일을 기준으로 컴파일 과정이 시작된다.
+
+
+
+
+## 2) 스캐너(Scanner)
+
+스캐너는 타입스크립트 소스 파일을 어휘적으로 분석하여 토큰을 생성하는 역할을 한다.
+소스코드를 작은 단위로 나누어 의미 있는 토큰으로 변환하는 작업을 수행한다.
+
+```ts
+// 코드는 스캐너에 의해 다음과 같은 토큰으로 분석된다.
+const woowa = "bros";
+```
+
+- ConstKeyword: const
+- WhitespaceTrivia: (공백)
+- Identifier: woowa
+- WhitespaceTrivia: (공백)
+- EqualsToken: =
+- WhitespaceTrivia: (공백)
+- StringLiteral: "bros"
+- SemicolonToken: ;
+
+
+
+
+## 3) 파서(Parser)
+
+스캐너가 소스 파일을 토큰으로 나눠주면, 파서는 그 토큰 정보를 이용하여 AST를 생성한다.
+
+파서는 생성된 토큰 목록을 활용하여 구문적 분석을 수행한다.
+
+코드의 실질적인 구조를 노드 단위의 트리 형태로 표현하고,
+각각의 노드는 코드상의 위치, 구문 종류, 코드 내용과 같은 정보를 담는다.
+
+### AST?
+
+컴파일러가 동작하는 데 핵심 기반이 되는 자료 구조로,
+소스코드의 구조를 트리 형태로 표현한다.
+
+AST의 최상위 노드는 타입스크립트 소스 파일이며,
+최하위 노드는 파일의 끝 지점으로 구성된다.
+
+
+
+
+## 4) 바인더(Binder)
+
+체커 단계에서 타입 검사를 할 수 있도록 기반을 마련하는 역할은 한다.
+바인더는 타입 검사를 위해 심볼이라는 데이터 구조를 생성한다.
+
+심볼은 이전 단계의 AST에서 선언된 타입의 노드 정보를 저장한다.
+
+```ts
+export interface Symbol {
+ flags: SymbolFlags; // Symbol flags
+ escapedName: string; // Name of Symbol
+ declarations?: Declaration[];
+ // ...
+}
+
+// src/compiler/types.ts
+export const enum SymbolFlags {
+ NONE = 0,
+ FunctionScopedVariable = 1 << 0, // Variable (var) or parameter
+ BloackScopedVariable = 1 << 1, // A block-scoped variable (let or const)
+ Property = 1 << 2, // Property or enum member
+ EnumMember = 1 << 3, // Enum member
+ Function = 1 << 4, // Function
+ Class = 1 << 5, // Class
+ Interface = 1 << 6, // Interface
+ ...
+ ..
+ .
+}
+```
+
+- flags 필드는 AST에서 선언된 타입의 노드 정보를 저장하는 식별자이다.
+- 심볼 인터페이스의 declarations 필드는 AST 노드의 배열 형태를 보인다.
+
+> 바인더는 심볼을 생성하고 해당 심볼과 그에 대응하는 AST 노드를 연결하는 역할을 한다.
+
+```ts
+type SomeType = string | number;
+interface SomeInterface {
+ name: string;
+ age?: number;
+}
+
+let foo: string = "LET";
+const obj = {
+ name: "이름",
+ age: 10,
+};
+
+class MyClass {
+ name;
+ age;
+
+ constructor(name: string, age?: number) {
+ this.name = name;
+ this.age = age ?? 0;
+ }
+}
+
+const arrowFunction = () => {};
+function func() {}
+
+arrowFunction();
+func();
+
+const colin = new Class("colin");
+```
+
+
+
+
+
+
+## 5) 체커(Checker)와 이미터(Emitter)
+
+### 체커?
+
+체커는 파서가 생성한 AST와 바인더가 생성한 심볼을 활용해 타입 검사를 수행한다.
+
+체커의 주요 역할은 AST의 노드를 탐색하면서
+심볼 정보를 불러와 주어진 소스 파일에 대해 타입 검사를 진행하는 것이다.
+체커의 타입 검사는 다음 컴파일 단계인 이미터에서 실행된다.
+
+checker.ts의 getDiagnostics() 함수를 사용해 타입을 검증하고
+타입 에러에 대한 정보를 보여줄 에러 메시지를 저장한다.
+
+### 이미터?
+
+타입스크립트 소스 파일을 변환하는 역할을 한다.
+즉, 타입스크립트 소스를 자바스크립트 파일(.js)과 타입 선언 파일(d.ts)로 생성한다.
+
+타입스크립트 소스 파일을 변환하는 과정에서
+개발자가 설정한 타입스크립트 설정파일을 읽어오고,
+체커를 통해 코드에 대한 타입 검증 정보를 가져온다.
+
+emitter.ts 소스 파일 내부의 emitFiles() 함수를 사용해
+타입스크립트 소스 변환을 진행한다.
+
+
+
+
+## 6) 타입스크립트의 컴파일 과정
+
+1. tsc 명령어를 실행해 프로그램 객체가 컴파일 과정을 시작한다.
+2. 스캐너는 소스 파일을 토큰 단위로 분리한다.
+3. 파서는 토큰을 이용해 AST를 생성한다.
+4. 바인더는 AST의 각 노드에 대응하는 심볼을 생성한다. 심볼은 선언된 타입의 노드 정보를 담고 있다.
+5. 체커는 AST를 탐색하며 심볼 정보를 활용해 타입 검사를 수행한다.
+6. 타입 검사 결과 에러가 없다면 이미터를 사용해서 자바스크립트 소스 파일로 변환한다.
+
+
+
diff --git "a/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.1_API_\354\232\224\354\262\255/seulgi.md" "b/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.1_API_\354\232\224\354\262\255/seulgi.md"
index 3beced8..c697d7a 100644
--- "a/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.1_API_\354\232\224\354\262\255/seulgi.md"
+++ "b/CH07_\353\271\204\353\217\231\352\270\260_\355\230\270\354\266\234/7.1_API_\354\232\224\354\262\255/seulgi.md"
@@ -1 +1,365 @@
-
+# 1. API 요청
+
+## 1) fetch로 API 요청하기
+
+장바구니 조회 기능을 만들기 위해 외부 데이터베이스에 접근해
+사용자가 장바구니에 추가한 정보를 호출하는 코드를 작성한다고 해보자.
+
+아래는 fetch 함수를 이용해 사용자가 담은 장바구니 물품 개수를 배지로 만든 예시이다.
+
+```tsx
+const CartBadge = () => {
+ const [cartCount, setCartCount] = useState(0);
+
+ useEffect(() => {
+ fetch("").then.((response) => response.json()).then(({cartItem} => {
+ setCartCount(cartItem.length);
+ }))
+ },[]);
+
+ return (
+ // 렌더링 로직
+ );
+}
+```
+
+위의 경우처럼 구현해 다른 컴포넌트에서도 사용할 경우에
+
+백엔드에서 기능 변경을 해야해 API URL을 수정해야 한다면,
+이미 컴포넌트 내부 깊숙이 자리 잡은 비동기 호출 코드는 이런 변경 요구에 취약하다.
+
+그 외에도 커스텀 헤더, 타임아웃 설정과 같은 정책이 추가될 때마다 수정의 번거로움이 생긴다.
+
+
+
+
+## 2) 서비스 레이어로 분리하기
+
+여러 API 변경으로 코드가 변경될 수 있다는 걸 감안해,
+비동기 호출 코드는 컴포넌트 영역에서 분리되 서비스 레이어에서 처리되어야 한다.
+
+단순히, fetch 함수 호출 부분을 서비스 레이어로,
+컴포넌트는 서비스 레이어 비동기 함수를 호출해 그 결과를 받아
+렌더링하는 흐름만으로는 API 요청 정책이 추가되는 것을 해결하기 어렵다.
+
+예를 들어, fetch함수에서 타임아웃을 설정하기 위해서는 다음 같이 구현해야 한다.
+
+```tsx
+async function fetchCart() {
+ const controller = new AbortController();
+
+ const timeoutId = setTimeout(() => controller.abort(), 5000);
+
+ const response = await fetch("url", {
+ signal: controller.signal,
+ });
+
+ clearTimeout(timeoutId);
+
+ return response;
+}
+```
+
+
+
+
+## 3) Axios 활용하기
+
+fetch는 내장 라이브러리라 설치 필요는 없지만, 많은 기능을 사용하려면 직접 구현해야 한다.
+이런 번거로움 때문에 fetch 함수를 직접 쓰는 대신 Axios 라이브러리를 사용한다.
+
+```tsx
+const apiRequester: AxiosInstance = axios.create({
+ baseURL: "url",
+ timeout: 5000,
+});
+
+const fetchCart = (): AxiosPromise =>
+ apiRequester.get("cart");
+
+const postCart = (
+ postCartRequest: PostCartRequest
+): AxiosPromise =>
+ apiRequester.post("cart", postCartRequest);
+```
+
+### API Entry가 2개 이상일 경우
+
+```tsx
+const apiRequester: AxiosInstance = axios.create(defaultConfig);
+
+const orderApiRequester: AxiosInstance = axios.create({
+ baseURL: "url",
+ ...defaultConfig,
+});
+const orderCartApiRequester: AxiosInstance = axios.create({
+ baseURL: "url",
+ ...defaultConfig,
+});
+```
+
+각 서버의 기본 URL을 호출하도록 orderApiRequester, orderCartApiRequester 같이
+2개 이상의 API 요청을 처리하는 인스턴스를 따로 구성해야 한다.
+
+이후, 다른 URL로 서비스 코드를 호출할 때는 각각의 apiRequester를 사용하면 된다.
+
+
+
+
+## 4) Axios 인터셉터 사용하기
+
+서로 다른 역할을 담당하는 다른 서버이기 때문에
+requester별로 다른 헤더를 설정해줘야 하는 로직이 필요할 수 있다.
+
+이때, 인터셉터 기능을 사용하여 requester에 따라 비동기 호출 내용을 추가해서 처리할 수 있다.
+또한 API 에러를 처리할 때 하나의 에러 객체로 묶어서 처리할 수도 있다.
+
+이와 달리 요청 옵션에 따라 다른 인터셉터를 만들기 위해 빌더 패턴을 추가하여
+APIBuilder 같은 클래스 형태로 구성하기도 한다.
+
+> **빌더 패턴(Builder Pattern)?**
+> 객체 생성을 더 편리하고 가독성 있게 만들기 위한 디자인 패턴 중 하나다.
+> 주로 복잡한 객체의 생성을 단순화하고, 객체 생성 과정을 분리하여 객체를 조립하는 방법을 제공한다.
+
+다만, 이런 APIBuilder 클래스는 보일러플레이트 코드가 많다는 단점을 갖고 있기 때문에
+옵션이 다양한 경우 인터셉터를 설정값에 따라 적용하고,
+필요 없는 인터셉터를 선택적으로 사용할 수 있다는 장점도 갖고 있다.
+
+
+
+
+## 5) API 응답 타입 지정하기
+
+API 응답 값은 하나의 Response 타입으로 묶일 수 있다.
+
+```ts
+interface Response {
+ data: T;
+ status: string;
+ serverDataTime: string;
+ errorCord?: string;
+ errorMessage?: string;
+}
+
+const fetchCart = (): AxiosPromise =>
+ apiRequester.get < Response < FetchCartResponse >> "cart";
+
+const postCart = (
+ postCartRequest: PostCartRequest
+): AxiosPromise =>
+ apiRequester.post>("cart", postCartRequest);
+```
+
+이와 같이 서버에서 오는 응답을 통일할 때 주의할 점은
+Response 타입을 apiRequester 내에서 처리한다면
+UPDATE, CREATE 같이 응답이 없을 수 있는 API 처리가 까다로워질 수 있다.
+
+따라서, Response 타입은 apiRequester가 모르게 관리되어야 하고,
+해당 값에 어떤 응답이 들어있는지 알 수 없거나 값의 형식이 달라지더라도
+로직에 영향을 주지 않는 경우에는 unknown 타입을 사용하여 알 수 없는 값임을 표현한다.
+
+```ts
+interface response {
+ data: {
+ cartItems: CartItem[];
+ forPass: unknown;
+ };
+}
+```
+
+다만, 이미 설계된 프로덕트에서 쓰고 있는 값이라면
+프로트 로직에서 써야 하는 값에 대해서만 타입을 선언한 다음에 사용하는 것이 좋다.
+
+```ts
+type ForPass = {
+ type: "A" | "B" | "C";
+};
+
+const isTargetValue = () => (data.forPass as ForPass).type === "A";
+```
+
+
+
+
+## 6) 뷰 모델 사용하기
+
+새로운 프로젝트는 서버 스펙이 자주 바뀌기 때문에
+뷰 모델을 사용하여 API 변경에 따른 범위를 한정해줘야 한다.
+
+```tsx
+interface ListResponse {
+ items: ListItem[];
+}
+
+const fetchList = async (filter?: ListFetchFilter): Promise => {
+ const { data } = await api
+ .params({ filter })
+ .get("/api/get-list")
+ .call>();
+
+ return { data };
+};
+
+const ListPage = () => {
+ const [itemCount, setItemCount] = useState(0);
+ const [items, setItems] = useState([]);
+
+ useEffect(() => {
+ fetchList(filter).then(({items}) => {
+ setItemCount(items.length);
+ setItems(items);
+ })
+ },[]);
+
+ return (
+ // 렌더링 로직
+ );
+};
+```
+
+흔히 좋은 컴포넌트는 변경될 이유가 하나뿐인 컴퍼넌트라 한다.
+
+API응답의 items 인자를 좀 더 정확한 개념으로 나타내기 위해
+각 역할에 맞는 컴포넌트명으로 바꾼다면 해당 컴포넌트도 수정해야 하는데
+같은 API를 사용하는 기존 컴포넌트들 모두 수정해야하는 문제가 생긴다.
+
+이 문제를 해결하기 위한 방법으로 뷰 모델을 도입할 수 있다.
+
+API 응답에는 없는 ItemCount와 같은 도메인 개념을 넣을 때도
+백엔드나 UI에서 로직을 추가하여 처리할 필요 없이 간편하게 새로운 필드를 뷰 모델에 추가할 수 있다.
+
+### 뷰 모델에도 문제는 있다?!
+
+추상화 레이어 추가는 결국 코드를 복잡하게 만들며 레이어를 관리하고 개발하는 비용이 든다.
+
+```tsx
+interface JobListResponse {
+ jobItems: JobListItemResponse[];
+}
+
+class JobListItem {
+ constructor(item: JobListItemResponse) {
+ // JobListItemResponse => JobListItem 객체로 변환
+ }
+}
+
+class JobList {
+ readonly itemCount: number;
+ readonly items: JobListItemResponse[];
+
+ constructor({ jobItems }: JobListResponse) {
+ this.itemCount = jobItem.length;
+ this.items = jobItems.map((item) => new JobListItem(item));
+ }
+}
+
+const fetchJobList = async (
+ filter?: ListFetchFilter
+): Promise => {
+ const { data } = await api
+ .params({ filter })
+ .get("/api/get-list")
+ .call>();
+
+ return new JobList(data);
+};
+```
+
+### 도메인의 일관성 + 코드 수정 비용의 절충안을 찾자!
+
+1. 필요한 곳에만 뷰 모델을 부분적으로 만들어서 사용하기
+2. 백엔드와 클라이언트 개발자가 충분히 소통 후에 개발해 API 응답 변화 줄이기
+3. 뷰 모델에 필드를 추가하기 대신에 getter 등 함수를 추가해 실제 어떤 값이 뷰 모델에 추가한 값인지 알기 쉽게 하기
+
+### AI로 찾아본 각 예시들
+
+1. 필요한 곳에만 뷰 모델(ViewModel)을 부분적으로 만들어서 사용하기
+
+- 전체 도메인 객체를 뷰에 억지로 끼워 맞추기보다는, 필요한 정보만 추려서 가볍게 사용하자.
+
+```ts
+// 전체 도메인 모델
+interface User {
+ id: number;
+ name: string;
+ email: string;
+ birthday: string;
+ createdAt: string;
+ updatedAt: string;
+}
+
+// 뷰 모델 (뷰에서 필요한 정보만 선택)
+interface UserProfileViewModel {
+ name: string;
+ birthday: string;
+}
+
+// 사용처에서 가볍게 매핑
+const toUserProfileViewModel = (user: User): UserProfileViewModel => ({
+ name: user.name,
+ birthday: user.birthday,
+});
+```
+
+
+
+2. API 응답 스펙의 변경을 줄이기 위해 백엔드/프론트 간 소통 강화
+
+- 프론트와 백엔드가 협의해서 “이건 프론트에서 계산할게요” 또는 “백엔드가 계산해서 내려줄게요” 협의한다고 가정하자.
+
+```ts
+{
+"price": 1000,
+"discount": 100
+}
+
+// 클라이언트에서 totalPrice 계산
+const totalPrice = price - discount;
+```
+
+- 백엔드에서 계산 요청하고 응답 스펙을 바꾸지 않음 (기존 유지)
+- 프론트에서는 필요한 값을 뷰 모델에서 따로 계산
+
+
+
+3. 뷰 모델에 필드를 직접 추가하지 말고 함수(getter)를 통해 표현
+
+- 어떤 값이 기존 도메인에서 온 값인지, 아니면 UI용 가공값인지 명확히 하자.
+
+```ts
+interface Product {
+ name: string;
+ price: number;
+ discount: number;
+}
+
+// 뷰 모델 형태로 가공
+class ProductViewModel {
+ constructor(private product: Product) {}
+
+ get name() {
+ return this.product.name;
+ }
+
+ get price() {
+ return this.product.price;
+ }
+
+ get finalPrice() {
+ return this.product.price - this.product.discount;
+ }
+
+ // UI에서만 사용하는 값
+ get isOnSale() {
+ return this.product.discount > 0;
+ }
+}
+```
+
+- 이 방식은 실제 데이터는 그대로 두고, 추가된 값들이 어떤 용도인지 명확하게 드러나고,
+- finalPrice, isOnSale은 UI 전용이라는 게 getter로 구분되어 이해하기 쉽다.
+
+> 다만, 타입스크립트는 정적 검사 도구라 런타임에 API 응답의 타입 오류를 방지하려면 Superstruct, zod같은 라이브러리를 사용하면 된다.
+
+
+
diff --git a/assets/CH06/kind_of_symbol.png b/assets/CH06/kind_of_symbol.png
new file mode 100644
index 0000000..e124044
Binary files /dev/null and b/assets/CH06/kind_of_symbol.png differ