diff --git "a/CH01_\353\223\244\354\226\264\352\260\200\353\251\260/1.1_\354\233\271_\352\260\234\353\260\234\354\235\230_\354\227\255\354\202\254/seulgi.md" "b/CH01_\353\223\244\354\226\264\352\260\200\353\251\260/1.1_\354\233\271_\352\260\234\353\260\234\354\235\230_\354\227\255\354\202\254/seulgi.md" index 3beced8..7498b76 100644 --- "a/CH01_\353\223\244\354\226\264\352\260\200\353\251\260/1.1_\354\233\271_\352\260\234\353\260\234\354\235\230_\354\227\255\354\202\254/seulgi.md" +++ "b/CH01_\353\223\244\354\226\264\352\260\200\353\251\260/1.1_\354\233\271_\352\260\234\353\260\234\354\235\230_\354\227\255\354\202\254/seulgi.md" @@ -1 +1,93 @@ - +# 웹 개발의 역사 + +## 1) 자바스크립트의 탄생 + +- 1990년대, 마이크로소프트의 "인터넷 익스플로러"와 넷스케이프 커뮤니케이션즈의 "넷스케이프 네비게이터"가 많이 사용되는 웹 브라우저였다. +- 1995년, 다양한 콘텐츠 표현을 위해 새로운 언어가 필요해지고 Javascript가 탄생했다. + +### Javascript는 어떤 언어였는가? + +- C, 자바와 같은 언어와 유사한 기본 문법 +- 객체 지향 언어인 셀프(Self)의 프로토타입 기반 상속 개념 +- Lisp 계열 언어 중 하나인 스킴(Scheme)의 일급 함수 개념 + +위의 개념들이 차용된 경량의 프로그래밍 언어였다. + +> [!NOTE] +> **Self언어?**
+> 1980년대 후반에 Sun Microsystems에서 개발한 객체지향 프로그래밍 언어. Smalltalk에서 영향을 받았고, 프로토타입 기반 프로그래밍(Prototype-based Programming) 개념을 중심으로 설계되었다.
특징으로는 클래스가 없고, 메세지 기반 프로그래밍으로 객체들 간 메세지를 주고받으며 동작하는 동적 타이핑 언어다. + +> [!NOTE] +> **Lisp 계열 언어?**
Lisp(LISt Processing)은 1958년에 개발된 함수형 프로그래밍 언어 중 하나로 코드를 데이터처럼 다룰 수 있는 유연한 구조가 특징이고, 수많은 Lisp 계열 언어가 파생되었다.
모든 것이 리스트(List) → (함수 인자1 인자2 ...) 형태로 코드와 데이터 경계가 없고 메모리 관리를 자동으로 수행하는 동적 타이핑 언어이다. + +

+ +## 2) 자바스크립트 표준, ECMAScript의 탄생 + +### 기존의 웹 브라우저 경쟁 구도에서 문제점을 알아보자! + +경쟁 상대이던 넷스케이프와 마이크로소프트가 각각 자신들의 브라우저에 새로운 기능을 늘렸으나 각 추가 기능들은 각자의 브라우저에만 동작했다. + +DOM구조가 다르기에 크로스 브라우징 이슈로 인해 개발자들은 두 개의 스크립트를 따로 개발해야 하는 어려움이 있었다. 브라우저는 자바스크립트의 변화를 따라가지 못했고, 자바스크립트에 추가되는 기능은 런타임 환경인 브라우저에서도 이 기능을 지원할 수 있어야 하는데 + +새로운 버전의 브라우저가 출시되 자바스크립트의 새로운 기능을 지원하더라도 +사용자가 예전 버전의 브라우저를 사용한다면 이 기능이 무용지물되는 문제를 해결하기 위해 +자바스크립트에서는 **폴리필(Polyfill), 트랜스파일(transpile)** 과 같은 개념이 등장했다. + +> [!NOTE] +> **폴리필(Polyfill), 트랜스파일(transpile)**
폴리필은 브라우저에서 사용할 수 있도록 변환한 코드 조각이나 플러그인이고, 트랜스파일은 최신 버전의 코드를 예전 버전의 코드로 변환하는 과정이다. (유명한 폴리필 라이브러리로 core.js와 polyfill.io가 있고, 트랜스파일러로는 babel이 있다.) + +### 자바스크립트 표준화 문제가 대두되다..! + +이런 문제들과 jQuery와 같이 브라우저 호환성을 고민하지 않아도 되는 라이브러리만으로는 해결할 수 없었고,
+모든 브라우저에서 동일하게 동작되는 표준화된 자바스크립트의 필요성이 제기되었다. + +넷스케이프는 컴퓨터 시스템 표준을 관리하는 Ecma 인터내셔널에 자바스크립트 표준화를 위한 자바스크립트 기술 규격을 제출했다. + +Ecma 인터내셔널은 ECMAScript라는 이름으로 자바스크립트 표준화를 공식화했다. + +> 정적 웹사이트에서 동적 웹 애플리케이션으로의 전환이 가속화된 계기! + +

+ +## 3) 웹사이트에서 웹 애플리케이션으로의 전환 + +### 웹사이트? + +웹사이트도 물론 HTML, CSS와 더불어 자바스크립트로 구축한 사례가 있지만, +웹사이트는 수집된 데이터 및 정보를 특정 페이지에 표시하기 위한 정적인 웹이다. + +- 단방향 정보 제공이기 때문에 사용자와 상호 작용하지 않는다. +- HTML에 링크가 연결된 웹페이지 모음 +- 콘텐츠가 동적으로 업데이트 되지 않는다. + +### 웹 애플리케이션? + +사용자와 상호작용하는 쌍방향 소통의 웹. +검색, 댓글, 좋아요 등 웹 페이지 내부에 수많은 애플리케이션이 동작하고 있기 때문에 이렇게 부른다. + +

+ +## 4) 개발 생태계의 발전 + +대규모 웹 서비스 개발의 필요성이 커지며 웹 페이지를 통이 아닌 컴포넌트 단위로 개발하는 방식이 생겨났다. (+ Ajax로 비동기 요청을 해서 페이지 일부 데이터를 로드도 가능해졌다.) + +웹 서비스가 웹 애플리케이션 특성을 지니게 되면서 컴포넌트 베이스 개발 방법론(CBD)이 등장했다. + +### CBD(Component Based Development?) + +서비스에서 다루는 데이터를 구분하고 그에 맞는 UI를 표현할 수 있게 컴포넌트 단위로 개발하는 접근 방식이다. 재사용할 수 있는 컴포넌트를 개발 또는 조합해서 하나의 애플리케이션을 만드는 개발 방법론이다. + +- 컴포넌트는 모듀로가 유사하게 하나의 독립된 기능을 재사용하기 위한 코드 묶음 +- 모듈과는 달리 런타임 환경에서 독립적으로 배포/실행할 수 있는 단위 +- 다른 컴포넌트와의 의존성을 최소화하거나 없애야 한다. + +### 의존성이란? + +의존하고 있는 대상의 변경에 영향을받을 수 있는 가능성. + +

+ +## 5) 개발자 협업의 필요성 증가 + +결과물이 커졌기에 서비스 개발 이후 유지보수를 하는 데 협업의 중요성이 높아졌다. diff --git "a/CH01_\353\223\244\354\226\264\352\260\200\353\251\260/1.2_\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\355\225\234\352\263\204/seulgi.md" "b/CH01_\353\223\244\354\226\264\352\260\200\353\251\260/1.2_\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\355\225\234\352\263\204/seulgi.md" index 3beced8..fe64062 100644 --- "a/CH01_\353\223\244\354\226\264\352\260\200\353\251\260/1.2_\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\355\225\234\352\263\204/seulgi.md" +++ "b/CH01_\353\223\244\354\226\264\352\260\200\353\251\260/1.2_\354\236\220\353\260\224\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\355\225\234\352\263\204/seulgi.md" @@ -1 +1,83 @@ - +# 자바스크립트의 한계 + +## 1) 동적 타입 언어 + +자바스크립트는 동적 타입 언어라 코드가 실행되는 런타임에 변숫값이 할당될 때 해당 값의 타입에 따라 변수 타입이 결정된다. + +
+
+ +## 2) 동적 타이핑 시스템의 한계 + +```js +const sumNumber = (a, b) => { + return a + b; +}; + +sumNumber(100); // NaN; +sumNumber("a", "b"); // "ab" +``` + +위의 예시처럼 숫자를 계산하려는 함수로 의도했지만 의도와 다르게 동작할 수 있는 문제가 있다. 동적 타입 언어라는 특성으로 함수를 호출할 때 사용되는 인수 값에 따라 a,b 타입이 결정되기 때문이다. + +자바스크립트 엔진에서는 주석, 함수 이름, 개발자의 의도는 고려 대상이 아니다. + +
+
+ +## 3) 한계 극복을 위한 해결 방안 + +자바스크립트 인터페이스의 필요성을 느끼고, JSDoc, propTypes, 다트 같은 해결 방안이 등장했다. + +### JSDoc + +- 모듈, 네임스페이스, 클래스, 메서드, 매개변수 등에 대한 API 문서 생성 도구다. +- 주석에 @ts-check를 추가하면 타입 및 에러 확인이 가능하다. +- 자바스크립트 소스코드에 타입 힌트를 제공하는 HTML 문서를 생성할 수 있다. +- 주석 사용이기 때문에 강제성을 부여하긴 어렵다. + +### propTypes + +- 리액트에서 props 타입 검사용으로 사용하는 속성이다. +- prop에 유효한 값이 전달되었는지 확인 가능한데, 전체 타입 검사는 어렵다. +- 리액트라는 특정 라이브러리만 사용 가능하다. + +### 다트 + +- 구글에서 자바스크립트 대체를 위한 새로운 언어이다. +- 타이핑이 가능하나, 새로운 언어라는 단점이 있다. + +
+
+ +## 4) 타입스크립트의 등장 + +마이크로소프트는 자바스크립트의 슈퍼셋 언어인 타입스립트를 공개했고 아래와 같은 장점을 지녀 많은 환영을 받았다. + +> [!NOTE] +> **슈퍼셋(Superset)?**
기존 언어에 새로운 기능과 문법을 추가해서 보완하거나 향상하는 것. 슈퍼셋 언어는 기존 언어와 호환되며 일반적으로 컴파일러 등으로 기존 언어 코드로 변환되어 실행된다. + +### (1) 안정성 보장 + +- 타입스크립트는 정적 타이핑을 제공해 컴파일 단계에서 타입 검사를 해줘 자바스크립트의 빈번한 타입 에러를 줄여준다. +- 런타임 에러를 사전에 방지해 안정성을 보장해준다. + +### (2) 개발 생산성 향상 + +- VSCode 등의 IDE에서 타입 자동 완성 기능을 제공한다. +- 변수와 함수 타입을 추론하고, 리액트 사용 시 어떤 prop을 넘겨야 하는지 매번 확인하지 않아도 되는 등 개발 생산성이 향상된다. + +> [!NOTE] +> **IDE (Integrated Development Environment, 통합 개발 환경)란?**
코드를 작성하고, 실행하고, 디버깅하는 모든 작업을 하나의 프로그램에서 할 수 있도록 도와주는 개발 도구. 쉽게 말해서 코딩에 필요한 모든 기능이 한곳에 모여 있는 소프트웨어이다. + +### (3) 협업에 유리 + +- 인터페이스, 제네릭 등으로 인터페이스가 기술되면 코드를 쉽게 이해할 수 있다. +- 자동 완성 기능이나 기술된 인터페이스로 코드를 쉽게 파악 가능하다. + +> [!NOTE] +> **타입스크립트 인터페이스?**
객체 구조를 정의한다. 특정 객체가 가져야 하는 속성과 메서드 집합을 인터페이스로 정의해 객체가 그 구조를 따르게 한다. + +### (4) 자바스크립트에 점진적으로 적용 가능 + +- 슈퍼셋 언어이기 때문에 점진적 도입이 가능하다. diff --git "a/CH02_\355\203\200\354\236\205/2.1_\355\203\200\354\236\205\354\235\264\353\236\200/seulgi.md" "b/CH02_\355\203\200\354\236\205/2.1_\355\203\200\354\236\205\354\235\264\353\236\200/seulgi.md" index 3beced8..d5cace8 100644 --- "a/CH02_\355\203\200\354\236\205/2.1_\355\203\200\354\236\205\354\235\264\353\236\200/seulgi.md" +++ "b/CH02_\355\203\200\354\236\205/2.1_\355\203\200\354\236\205\354\235\264\353\236\200/seulgi.md" @@ -1 +1,130 @@ - +# 타입이란 + +## 1) 자료형으로서의 타입 + +모든 프로그램이 언어는 변수를 선언하는 것부터 시작한다. + +### 변수란? + +프로그래밍 언어에서 변수란 값을 저장할 수 있는 공간이자 값을 가리키는 상징적인 이름이다.
+개발자는 변수를 선언하고 그 변수에 특정한 값인 데이터를 할당한다. + +### 변수에 저장할 수 있는 값의 종류를 알아보자. + +변수에 저장할 수 있는 값의 종류는 프로그래밍 언어마다 다르나 최신 ECMAScript 표준을 따르는 자바스크립트는 아래와 같은 데이터 타입(자료형)을 정의한다. + +- undefined +- null +- Boolean +- String +- Symbol +- Numeric(Number, BigInt) +- Object + +> 데이터 타입은 여러 종류의 데이터를 식별하는 분류 체계로 컴파일러에 값의 형태를 알려준다.
모든 데이터를 해석할 때는 데이터 타입 체계가 사용된다. + +
+
+ +## 2) 집합으로서의 타입 + +프로그래밍에서 타입은 수학의 집합과 유사하다.
+타입은 값이 가질 수 있는 유효한 범위의 집합이다. + +### 타입 시스템의 이점은 뭘까? + +타입 시스템은 코드에서 사용되는 **유효한 값의 범위를 제한해서 런타임에서 발생할 수 있는 유효하지 않은 값에 대한 에러를 방지**해준다. +유효하지 않는 값에 대해서는 집합에 속하지 않는 타입이라고 알려주며 에러가 발생한다. + +> 집합의 경계처럼 해당 값 안에 들어갈 수 있는 타입의 집합으로 제한해 옳지 않는 값이라면 에러를 미리 알려주는 것이다. + +```ts +function double(n: number) { + return n * 2; +} + +double("z"); // Error!! +``` + +또, 위의 예시처럼 일단 타입을 제한하면 타입스크립트 컴파일러는 함수를 호출할 때 호환되는 인자로 호출했는지를 판단한다. + +
+
+ +## 3) 정적 타입과 동적 타입 + +타입을 결정하는 시점에 따라 정적 타입(static type), 동적 타입(dynamic type)으로 분류할 수 있다. + +### 정적 타입(static type) 시스템? + +정적 타입 시스템에서는 모든 변수의 타입이 컴파일타임에 결정된다.
+C, 자바, 타입스크립트 등이 정적 타입 언어이다.
+번거로울 수 있지만 컴파일타임에 타입 에러를 발견할 수 있기 때문에 프로그램의 안정성을 보장할 수 있다. + +### 동적 타입(dynamic type) 시스템? + +변수 타입이 런타임에서 결정된다.
+파이썬, 자바스크립트가 대표적인 동적 타입 언어로 직접 타입 지정이 필요없다.
+다만, 언제 프로그램에 오류가 생길 지 모르는 불안감이 있다. + +> 런타입에서 타입을 예측할 수 없다면 매우 위험한 상황이다. + +### 컴파일타임과 런타임? + +개발자가 작성한 소스코드를 실행하려면 몇 가지 과정을 거쳐야 한다.
+시점에 따라 컴파일타임 / 런타임으로 구분 가능하다. + +기계(컴퓨터, 엔진)가 소스코드를 이해할 수 있도록 기계어로 변환되는 시점을 컴파일타임이라 한다.
이후 변환된 파일이 메모리에 적재되어 실행되는 시점을 런타임이라 부른다. + +> 소스코드 -> ( 컴파일 ) -> 기계어 -> 변환 파일 -> 메모리 적재 -> ( 런타임 ) -> 실행 + +
+
+ +## 4) 강타입과 약타입 + +모든 프로그래밍 언어에는 값의 타입이 존재한다. + +### 암묵적 타입 변환(implicit coercion/conversion)? + +개발자가 의도적으로 타입을 명시하거나 바꾸지 않았는데도 컴파일러 또는 엔진 등에 의해서 런타임에 타입이 자동으로 변경되는 것을 암묵적 타입 변환이라 한다. + +암묵적 변환은 다른 데이터 타입 간 연산을 할 수 있는 편리함을 제공하지만, 작성자의 의도와 다르게 동작해 오류가 발생할 가능성도 높다. + +> 암묵적 타입 변환 여부에 따라 타입 시스템을 "강타입(strongly type)", "약타입(weakly type)"으로 분류할 수 있다. + +### 강타입 (strongly type)? 약타입(weakly type)? + +#### 강타입 특징 언어에서는, + +서로 다른 타입을 갖는 값끼리 연산을 시도하면 컴파일러 또는 인터프리터에서 에러가 발생한다. + +> 파이썬, 루비, 타입스크립트 언어가 강타입! + +#### 약타입 특징을 갖는 언어에서는, + +서로 다른 타입을 갖는 값끼리 연산할 때는 컴파일러 또는 인터프리터가 내부적으로 판단해서 특정값의 타입을 변환하여 연산을 수행한 후 값을 도출한다. + +> C++, 자바, 자바스크립트는 약타입! + +### 타입시스템? + +타입 검사기가 프로그램에 타입을 할당하는 데 사용하는 규칙 집합을 **"타입시스템"** 이라고 한다. + +타입 시스템은 크게 두 가지로 구분된다. + +- 자동 타입 추론 시스템 +- 명시적으로 알려줘야하는 타입 시스템 + +타입스크립트는 두 가지 타입 시스템의 영향을 모두 받았고, 개발자는 직접 타입 명시 / 타입스크립트가 추론하는 방식 중에 선택할 수 있다. + +
+
+ +## 5) 컴파일 방식 + +컴파일의 일반적인 의미는 사람이 이해할 수 있는 방식으로 작성한 코드를 컴퓨터가 이해할 수 있는 기계어로 바꿔주는 과정이다. + +> 개발자 -> 고수준 언어로 소스코드 작성 -> 컴파일러 -> 바이너리 코드로 변환(고수준 - 저수준 간 코드 변환) + +그러나 타입스크립트의 **컴파일 결과물은 사람이 이해할 수 있는 방식인 자바스크립트 파일**이고, 타입스크립트를 컴파일하면 타입이 모두 제거된 **자바스크립트 소스코드만 남는다.** diff --git "a/CH02_\355\203\200\354\236\205/2.2_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\355\203\200\354\236\205_\354\213\234\354\212\244\355\205\234/seulgi.md" "b/CH02_\355\203\200\354\236\205/2.2_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\355\203\200\354\236\205_\354\213\234\354\212\244\355\205\234/seulgi.md" index 3beced8..2846416 100644 --- "a/CH02_\355\203\200\354\236\205/2.2_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\355\203\200\354\236\205_\354\213\234\354\212\244\355\205\234/seulgi.md" +++ "b/CH02_\355\203\200\354\236\205/2.2_\355\203\200\354\236\205\354\212\244\355\201\254\353\246\275\355\212\270\354\235\230_\355\203\200\354\236\205_\354\213\234\354\212\244\355\205\234/seulgi.md" @@ -1 +1,411 @@ - +# 타입스크립트의 타입 시스템 + +## 1) 타입 애너테이션 방식 + +### 타입 애너테이션(type annotaion)? + +변수나 상수 혹은 함수의 인자와 반환 값에 타입을 명시적으로 선언해서 어떤 타입 값이 저장될 것인지를 컴파일러에 직접 알려주는 문법이다. + +```ts +let isDone: boolean = false; +const CHU: string = "seulgi"; +``` + +타입 스크립트에서는 변수 이름 뒤에 `: type` 구문을 붙여 데이터 타입으 명시해준다.
+`: type` 선언부를 제거해도 코드가 정상적으로 동작하지만 타입 시스템이 타입 추론을 하는 과정에 어려움을 겪을 수도 있다. + +
+
+ +## 2) 구조적 타이핑 + +### 명목적 구체화 타입 시스템(Nominal Reified Type System)? + +값이나 객체는 하나의 구체적인 타입을 가지고 있다.
+타입은 이름으로 구분되며 컴파일타임 이후에도 남아있다. + +```cpp +class Animal { + String name; + int age; +} +``` + +서로 다른 클래스끼리 명확한 상속 관계나 공통으로 가지고 있는 인터페이스가 없다면 타입은 서로 호환되지 않는다. + +### 구조적 타이핑(Structural Type System)? + +타입스크립트에서 타입을 구분하는 방식은 이름으로 타입을 구분하는 명목적인 타입 언어의 특징과 달리 타입스크립트는 구조로 타입을 구분하는 것을 구조적 타이핑이라 한다. + +
+
+ +## 3) 구조적 서브타이핑 + +타입스크립트의 타입은 값의 집합(set of values)으로 생각할 수 있다. +타입은 단지 집합에 포함되는 값이고 특정 값은 많은 집합에 포함될 수 있다. + +> 따라서 타입스크립트에서는 특정 값이 string 또는 number 타입을 동시에 가질 수 있다. + +### 구조적 서브타이핑(Structural Subtyping)? + +집합으로 나타낼 수 있는 타입스크립트의 타입 시스템을 지탱하고 있는 개념이 바로 구조적 서브타이핑이다. + +객체가 가지고 있는 속성(프로퍼티)을 바탕으로 타입을 구분하는 것이다. 이름이 다른 객체라도 가진 속성이 동일하다면 타입스크립트는 서로 호환이 가능한 동일한 타입으로 여긴다. + +```ts +interface Pet { + name: string; +} + +interface Cat { + name: string; + age: number; +} + +let pet: Pet; +let cat: Cat = { name: "Chu", age: 2 }; + +// ✅ OK! +pet = cat; +``` + +> Cat, Pet는 다른 타입으로 선언되었지만 Pet이 갖고 있는 속성을 가지고 있어,
Cat 타입으로 선언한 cat도 Pet타입에 선언한 pet에 할당할 수 있다. + +```ts +interface Pet { + name: string; +} + +interface Cat { + name: string; + age: number; +} + +let cat: Cat = { name: "Chu", age: 2 }; + +function greet(pet: Pet) { + console.log("Hello" + pet.name); +} + +greet(cat); // ✅ OK! +``` + +> cat 객체는 Pet 인터페이스가 가지고 있는 name 속성을 가지고 있어 pet.name 방식으로 name 속성에 접근할 수 있는 타이핑 방식을 지원한다.( = 구조적 타이핑) + +### 서로 다른 두 타입 간이 호환성은 타입 내부의 구조에 의해 결정된다. + +타입 A가 타입 B의 서브타입이라면 A 타입의 인스턴스는 B 타입이 필요한 곳에 언제든지 위치할 수 있다. 즉 타입이 계층 구조로부터 자유롭다. + +
+
+ +## 4) 자바스크립트를 닮은 타입스크립트 + +명목적 타이핑을 채택한 언어에서는 이름으로 타입을 구분하기 때문에 구조가 같더라도 이름이 다르다면 다른 타입으로 취급한다. 명목적 타이핑은 타입의 동일성을 확인하는 과정에서 구조적 타이핑에 비해 조금 더 안전하다. + +즉, 객체의 속성을 다른 객체의 속성과 호환되지 않도록 하여 안전성을 추구한다. + +### 그럼에도 타입스크립트가 구조적 타이핑을 채택한 이유가 뭘까? + +타입스크립트가 자바스크립트를 모델링한 언어이기 때문이다.
+자바스크립트는 본질적으로 **덕 타이핑(duck typing)** 을 기반으로
+타입스크립트는 이런 동작을 그대로 모델링한다. + +> **덕 타이핑(duck typing)?**
+> 어떤 함수의 매개변숫값이 올바르게 주어진다면 그 값이 어떻게 만들어졌는지 신경 쓰지 않고 사용한다는 것이다. 어떤 타입에 부합하는 변수와 메서드를 가질 경우 해당 타입에 속하는 것. "만약 어떤 새가 오리처럼 걷고 헤엄치며 꽥꽥거리면 그 새도 오리다" + +구조적 타이핑 덕분에 타입스크립트는 더욱 유연한 타이핑이 가능해지고,
+쉬운 사용성과 안정성이라는 두 가지 목표 사이의 균형을 중시하는 타입스크립트에서는
+객체 간 속성이 동일하다면 서로 호환되는 구조적 타입 시스템을 제공해 편리성을 높였다. + +### 덕 타이핑과 구조적 타이핑의 차이는? + +타입을 검사하는 시점에서 차이가 있다.
+덕 타이핑은 런타임, 구조적 타이핑은 컴파일 타임에 타입을 검사한다. + +> 두 타이핑 모두 객체 변수, 메서드 같은 필드를 기반으로 타입을 검사한다는 점에서는 동일하지만 타입을 검사하는 시점이 다르다. + +
+
+ +## 5) 구조적 타이핑의 결과 + +구조적 타이핑의 특징 때문에 예기치 못한 결과가 나올 수 있다. + +```ts +interface Cube { + width: number; + height: number; + depth: number; +} + +function addLines(c: Cube) { + let total = 0; + + for (const axis of Object.keys(c)) { + const length = c[axis]; + + total += length; + } +} + +// Error: Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'Cube'. No index signature with a parameter of type 'string' was found on type 'Cube'. +``` + +> c에 들어올 객체는 Cube의 width, height, depth 속성 외에도 어떤 속성이든 가질 수 있기 때문에 c[axis] 타입이 string일 수 있어 에러가 발생한다. + +이러한 한계를 극복하고자 **타입스크립트에 명목적 타이핑 언어의 특징을 가미한 식별할 수 있는 유니온(Discriminated Unions) 같은 방법이 생겨났다.** + +
+
+ +## 6) 타입스크립트의 점진적 타입 확인 + +타입스크립트는 점진적으로 타입(gradually typed)을 확인하는 언어이다. + +### 점진적 타입(gradually type) 검사? + +컴파일타임에 타입을 검사하면서 필요에 따라 타입 선언 생략을 허용하는 방식이다.
+타입 선언이 생략되면 동적으로 검사를 수행하고 암시적 타입 변환이 일어난다. + +이처럼 타입스크립트에서는 필요에 따라 타입을 생략할 수도 있고 타입을 점진적으로 추가할 수도 있다. +그러나 타입스크립트는 컴파일타임에 프로그램의 모든 타입을 알고 있을 때 최상의 결과를 보여준다. + +### any 타입? + +타입스크립트 any 타입은 모든 타입의 종류를 포함하는 상위 타입으로 어떤 타입 값이든 할당할 수 있다. +단, 타입스크립트 컴파일 옵션인 noImplicitAny 값이 true일 때는 에러가 발생한다. + +
+
+ +## 7) 자바스크립트 슈퍼셋으로서의 타입스크립트 + +타입스크립트는 자바스크립트의 상위 집합으로 모든 자바스크립트 문법을 포함하고 있다. +모든 타입스크립트 코드가 자바스크립트 코드인 것은 아니고, 타입스크립트는 타입을 명시하는 뭄법을 가지고 있기 때문이다. + +
+
+ +## 8) 값 vs 타입 + +### 값의 특징을 알아보자. + +- 값은 프로그램이 처리하기 위해 메모리에 저장하는 모든 데이터이다. +- 프로그래밍 관점에서는 문자열, 숫자, 변수, 매개변수 등이 값에 해당된다. +- 객체 역시 값이며 함수도 역시 런타임에 객체로 변환되기 때문에 값이다. +- 값은 어떠한 식을 연산한 것으로 변수에 할당할 수 있다. + +> 자바스크립트 대신 타입스크립트를 사용하게 되면서 타입이라는 개념이 등장한다.
+> 타입스크립트는 변수, 매개변수, 객체 속성 등에 : type 형태로 타입을 명시한다. + +### 값과 다른 타입의 특징을 알아보자. + +- type, interface 키워드로 커스텀 타입을 정의할 수 있다. +- 타입스크립트 문법인 type으로 선언한 내용은 자바스크립트 런타임에서 제거되기 때문에 값 공간과 타입 공간은 서로 충돌하지 않는다. +- 타입은 주로 타입 선언(:), 단언 문(as)로 작성하고 값은 할당 연산자인 =으로 작성한다. +- 함수의 매개변수처럼 여러 개의 심볼이 함께 쓰이면 타입과 값을 명확하게 구분해야 한다. +- 값이 사용되는 위치와 타입이 사용되는 위치가 다르기에 코드가 어디에서 사용되었는지에 따라 추론할 수 있다. + +> 이처럼 타입스크립트에서는 값과 타입이 함께 사용되고, 값과 타입은 타입스크립트에서 별도의 네임스페이스에 존재한다. + +### 값 공간과 타입 공간을 혼동할 때도 있다! + +```ts +function email({ person: string, subject: string, body: string }) { + console.log(person + subject + body); +} // Error! + +// ✅ 올바른 예시 +function email({ + person, + subject, + body, +}: { + person: string; + subject: string; + body: string; +}) { + console.log(person + subject + body); +} +``` + + + +- 값의 관점에서 Person과 string이 해석되어 오류가 발생했다. +- person과 Person은 각 함수의 매개변수 객체 내부 속성의 키-값에 해당하는 것으로 해석한다. + +> 이와 같은 값-타입 공간으로 혼동하는 문제를 해결하기 위해 값과 타입을 구분해서 작성해야 한다. + +### 값과 타입 공간에 동시에 존재하는 심볼도 있다! + +대표적인 것이 클래스와 enum이다. 클래스는 객체 인스턴스를 더욱 쉽게 생성하기 위한 문법 기능으로 실제 동작은 함수와 같다. + +클래스는 타입으로도 사용되고, 타입스크립트 코드에서 클래스는 값과 타입 공간 모두에 포함될 수 있다. + +```ts +class Developer { + name: string; + domain: string; + + constructor(name: string, domain: string) { + this.name = name; + this.domain = domain; + } +} + +const me: Developer = new Developer("chu", "frontend"); +``` + +- 변수명 me 뒤의 `Developer`는 타입에 해당한다. +- `new` 키워드 뒤의 `Developer`는 클래스 생성자 함수인 값으로 동작한다. + +### enum 역시 값, 타입 둘 다 가능하다. + +enum 역시 런타임에 객체로 변환되는 값이다. 런타임에 실제 객체로 존재하며, 함수로 표현할 수 있다. + + + +> enum도 클래스처럼 타입 공간에서 타입을 제한하는 역할을 하지만 자바스크립트 런타임에서도 실제 값으로 사용될 수 있다. + +```ts +enum WeekDays { + MON = "Mon", + TUES = "Tues", + WEDNES = "Wednes", + THURS = "Thurs", + FRI = "Fri", +} + +// "MON" | "TUES" | "WEDNES" | "THURS" | "FRI" +type WeekDayKey = keyof typeof WeekDays; + +function printDay(key: WeekDayKey, message: string) { + const day = WeekDays[key]; + + if (day <= WeekDays.WEDNES) { + console.log(`It's still ${day}day, ${message}`); + } +} + +printDay("TUES", "wanna go home"); +``` + +> 해당 enum이 타입으로 사용되었다. keyof typeof 연산자를 사용해 타입을 만들어, 값의 타입을 제한하는 방식으로 사용했다. + +```ts +enum MyColors { + BLUE = "#0000FF", + PINK = "#FF00FF", +} + +function whatPinkColor(colors: { PINK: string }) { + return colors.PINK; +} + +whatPinkColor(MyColors); // ✅ +``` + +> 해당 예시예서 enum을 일반 객체처럼 동작한다. + +### 정리 + +타입스크립트에서 어떠한 심볼이 값으로 사용된다는 것은 컴파일러를 사용해서 타입스크립트 파일을 자바스크립트 파일로 변환해도 여전히 자바스크립트 파일에 남아있음을 의미한다. + +타입으로만 사용되는 요소는 컴파일 이후에 자바스크립트 파일에서 사라진다. + +### 타입스크립트에서 자바스크립트의 키워드가 해석되는 방식 + +| 키워드 | 값 | 타입 | +| --------------- | --- | ---- | +| class | Y | Y | +| const, let, var | Y | N | +| enum | Y | Y | +| function | Y | N | +| interface | N | Y | +| type | N | Y | +| namespace | Y | N | + +
+
+ +## 9) 타입을 확인하는 방법 + +`typeof`, `instanceof` 그리고 `타입 단언`을 사용해서 타입을 확인할 수 있다. + +### typeof + +- 연산하기 전에 피연산자의 데이터 타입을 나타내는 문자열을 반환한다. +- typeof가 반환하는 값은 자바스크립트 7가지 기본 데이터 타입이 될 수 있다. +- 타입스크립트에서는 값 공간과 타입 공간이 별도로 존재한다.(역할이 각각 다름) + +```ts +interface Person { + first: string; + last: string; +} + +const person: Person = { + first: "seulgi", + last: "chu", +}; + +function email(options: { person: Person; subject: string; body: string }) { + console.log(options); +} + +const v1 = typeof person; // 값은 "object" +type T1 = typeof person; // 타입은 Person + +const v2 = typeof email; // 값은 "function" +type T2 = typeof email; // 타입은 (ontions; {person: Person; subject: string; body: string; }) => void +``` + +> 값으로서 typeof : 자바스크립트 런타임의 typeof 연산자,
+> 타입에서 사용된 typeof : 값을 읽고 타입스크립트 타입을 반환한다. + +email 함수는 타입 공간에서 typeof 연산자로 값을 읽을 때 함수의 매개변수 타입과 리턴 타입을 포함한 함수 시그니처 타입을 반환한다. + +### 자바스크립트 클래스에서 typeof 연산자 사용에 주의하자! + +```ts +class Developer { + name: string; + sleepingTime: number; + + constructor(name: string; sleepingTime: number) { + this.name = name; + this.sleepingTime = sleepingTime; + } +} + +const d = typeof Developer; // 값이 "function" +type T = typeof Developer; // 타입이 typeof Developer +``` + +> 타입 공간에서 typeof Developer 반환값은 "typeof Developer"인데 type T에 할당된 Developer는 인스턴스 타입이 아니라 new 키워드를 사용할 때 볼 수 있는 생성자 함수이기 때문이다. + +### instanceof + +자바스크립트에서 instanceof 연산자를 사용하면 프로토타입 체이닝 어딘가 생성자 프로토타입 속성이 존재하는지 판단할 수 있다. + +instanceof 연산자의 필터링으로 타입이 보장된 상태에서 안전하게 값의 타입을 정제하여 사용할 수 있다. + +```ts +let error = unknown; + +if (error instanceof Error) { + // 로직 +} else { + throw Error(error); +} +``` + +### 타입 단언 + +타입을 강제할 수 있는데 `as` 키워드를 사용해 타입 단언을 한다. + +타입 단언은 개발자가 해당 값의 타입을 더 잘 파악할 수 있을 때 사용되며 강제 형 변환과 유사한 기능을 제공한다. + +> 타입스크립트는 컴파일 단계에서 타입 단언이 형 변환을 강제할 수 있지만 런타임에서는 효력을 발휘하지 못한다. 이외에도 타입을 검사하는 다른 방법으로 타입 가드가 있다. (특정 조건을 검사해 타입을 정제하고 타입 안정성을 높이는 패턴) diff --git "a/CH02_\355\203\200\354\236\205/2.3_\354\233\220\354\213\234_\355\203\200\354\236\205/seulgi.md" "b/CH02_\355\203\200\354\236\205/2.3_\354\233\220\354\213\234_\355\203\200\354\236\205/seulgi.md" index 3beced8..9381b8d 100644 --- "a/CH02_\355\203\200\354\236\205/2.3_\354\233\220\354\213\234_\355\203\200\354\236\205/seulgi.md" +++ "b/CH02_\355\203\200\354\236\205/2.3_\354\233\220\354\213\234_\355\203\200\354\236\205/seulgi.md" @@ -1 +1,135 @@ - +# 원시 타입 + +자바스크립트에서는 값은 타입을 가지지만 변수는 별도의 타입을 가지지 않기 때무네 어떤 타입 값이라도 자유롭게 할당할 수 있다. 타입스크립트는 이 변수에 타입을 지정할 수 있는 타입 시스템 체계를 구축한다. + +### 원시 값과 원시 래퍼 객체? + +자바스크립트 내장 타입을 파스칼 표기법으로 표기했다. +반면, 타입스크립트에서는 타입을 소문자로 표기하는데 자바스크립트는 컴파일 시점에 타입스크립트의 타입 시스템이 적용되지 않아 타입스크립트와의 구분을 위해 소문자로 표기하지 않았다. + +타입을 파스칼 표기법으로 표기하면 자바스크립트에서 이것을 원시 래퍼 객체로 부른다.
+`null`과 `undefined`를 제외한 모든 원시 값은 해당 원시 값을 래핑한 객체를 가진다. + +
+
+ +## 1) boolean + +```ts +const isEmpty: boolean = true; + +function isTextError(errorCode: ErroCodeType): boolean { + if (errorCode) { + return true; + } + + return false; +} +``` + +- true, false 값만 할당할 수 있는 타입 +- 위의 함수처럼 비교식의 결과 또한 boolean 타입을 가질 수 있다. +- 형 변환을 통해 true / false로 취급되는 `Truthy` / `Falsy` 값은 boolean 타입에 해당하지 않는다. + +
+
+ +## 2) undefined + +```ts +let value: string; +console.log(value); // undefined(값이 아직 할당되지 않음) +``` + +- 정의되지 않았다는 의미의 타입 +- 오직 undefined만 할당할 수 있다. +- 초기화되지 않은 값을 의미하며 변수 선언만 하고 값을 할당하지 않을 때나 옵셔널로 지정되어 있을 때 undefined를 할당할 수 있다. + +> 즉, 초기화되어 있지 않거나, 존재하지 않음을 나타낸다. + +
+
+ +## 3) null + +- null만 할당이 가능하다. +- 자바스크립트에서 빈 값을 할당할 때 사용하는 등 명시적 / 의도적으로 값이 아직 비어있을 수 있음을 보여준다. +- undefined와 비슷하지만 엄연히 따로 존재하는 원시 값이기 때문에 서로의 타입에 할당할 수 없다. + +### null과 undefined의 차이를 보여주는 예시를 살펴보자. + +```ts +type Person1 = { + name: string; + job?: string; +}; + +type Person2 = { + name: string; + job: string | null; +}; +``` + +- Person1은 job이라는 속성이 있을 수도 없을 수도 있음을 나타낸다.(job이라는 속성 유무를 통해 무직인지 아닌지를 나타냄) +- Person2는 job이라는 속성을 사람마다 갖고 있지만 값이 비어있을 수도 있다는 것을 나타낸다. (명시적인 null을 할당해 무직 상태를 나타냄) + +
+
+ +## 4) number + +- 숫자에 해당하는 모든 원시 값을 할당할 수 있다. +- 자바스크립트의 숫자는 정수, 부동소수점수를 구분하지 않기 때문에 모두 number 타입에 할당 가능하다. +- NaN이나 Infinity도 포함된다. + +
+
+ +## 5) bigInt + +```ts +const bigNumber1: bigInt = BigInt(999999999999); +``` + +- ES2020에 새롭게 도입된 데이터 타입 +- 타입스크립트 3.2버전부터 사용할 수 있다. +- 자바스크립트에서는 가장 큰 수인 Number.MAX_SAFE_INTEGER($2^{53}$ - 1)을 넘어가는 값을 처리할 수 없었는데 bigInt를 사용하면 된다. +- number타입과 상호 작용은 불가능하다. + +
+
+ +## 6) string + +- 문자열을 할당할 수 있는 타입 +- 공백, 작은따옴표, 큰따옴표 문자열 외에도 백틱으로 감싼 문자열 내부에 변숫값을 포함할 수 있는 템플릿 리터럴(template literal) 문법도 포함된다. + +
+
+ +## 7) symbol + +```ts +const MOVIE_TITLE = Symbol("title"); +const MUSIC_TITLE = Symbol("title"); + +console.log(MOVIE_TITLE === MUSIC_TITLE); // false + +let SYMBOL: unique symbol = Symbol(); // Error! +``` + +- ES2015에 도입된 타입으로 Symbol() 함수를 사용하면 어떤 값과도 중복되지 않는 유일한 값을 생성한다. +- 타입스크립트에서는 symbol 타입과 const 선언에서만 사용할 수 있는 unique symbol 타입이라는 symbol의 하위 타입도 있다. + +
+
+ +## 8) 마무리 + +null이나 undefined는 tsconfig 옵션이나 사용자 취향에 따라 다르게 사용될 여지가 있다. + +타입스크립트의 모든 타입은 기본적으로 null과 undefined를 포함하고 있다. +tsconfig의 strictNullChecks 옵션을 활성화했을 때는 사용자가 명시적으로 해당 타입에 null이나 undefined를 포함해야만 null과 undefined를 사용할 수 있다. + +보통은 null과 undefined를 `타입 가드`로 걸러내거나 `!연산자`를 사용해 타입을 단언하기도 한다. +일반적으로는 타입 가드를 사용하는 것이 더 안전하다고 여겨지기도 한다. diff --git "a/CH02_\355\203\200\354\236\205/2.4_\352\260\235\354\262\264_\355\203\200\354\236\205/seulgi.md" "b/CH02_\355\203\200\354\236\205/2.4_\352\260\235\354\262\264_\355\203\200\354\236\205/seulgi.md" index 3beced8..0dfed1d 100644 --- "a/CH02_\355\203\200\354\236\205/2.4_\352\260\235\354\262\264_\355\203\200\354\236\205/seulgi.md" +++ "b/CH02_\355\203\200\354\236\205/2.4_\352\260\235\354\262\264_\355\203\200\354\236\205/seulgi.md" @@ -1 +1,115 @@ - +# 객체 타입 + +원시 타입에 속하지 않는 값은 모두 객체 타입으로 분류할 수 있다. +객체의 범주는 원시 타입에 비해 굉장히 넓다. + +객체마다 개별적으로 타입을 지정할 수 있고, 배열 또는 클래스를 타입으로 지정할 수 있으며 매우 복잡한 구조를 가진 객체도 타입으로 만들어 관리할 수 있다. + +## 1) object + +객체의 정의에 맞게 이에 대응하는 타입스크립트 타입 시스템은 object 타입이다. + +- object 타입을 가급적 사용하지 말도록 권장되는데, 나중에 다룰 any타입과 유사하게 객체에 해당하는 모든 타입 값을 유동적으로 할당할 수 있다. +- any와 다르게 원시 타입에 해당하는 값은 object 타입에 속하지 않는다. +- 객체, 배열, 정규 표현식, 함수, 클래스 등 모두 object 타입과 호환된다. + +
+
+ +## 2) {} + +객체 리터럴 방식으로 객체를 생성할 때 사용한다. +타입스크립트에서 객체를 타이핑할 때도 중괄호를 쓸 수 있는데, 중괄호 안에 객체의 속성 타입을 지정해주는 식으로 사용한다. + +- 자바스크립트와 마찬가지로 빈 객체임을 의미한다. +- {} 타입으로 지정된 객체에는 어떤 값도 속성으로 할당할 수 없다. +- 빈 객체 타입 지정을 {}보다는 유틸리티 타입으로 Recode처럼 사용하는 게 더 바람직하다. + +```ts +let noticePopup: {} = {}; +noticePopup.title = "팝업 안내"; // Error! +``` + +{} 타입으로 지정된 객체는 완전히 비어있는 순수한 객체라는 의미가 아니고, Object 객체 래퍼에서 제공하는 속성에는 정상적으로 접근 가능하다. + +타입스크립트에서 객체 래퍼를 타입으로 지정할 수 있는 데도 이런 이유때문에 소문자로 된 타입을 사용하는 게 일반적이다. + +```ts +console.log(noticePopup.toString()); // [object Object] +``` + +
+
+ +## 3) array + +자바스크립트에서는 객체 자료구조 외에도 배열, 함수 정규식 등이 객체 범주에 속한다. 타입스크립트에서는 이 각각의 객체에 타입을 지정할 수 있다. + +- 배열을 array라는 별도의 타입으로 다룬다. +- 배령 타입은 하나의 타입 값만 가질 수 있다는 점에서 자바스크립트보다 조금 더 엄격하다. (원소 개수는 타입에 영향을 주지 않는다.) +- 배열 타입을 선언하는 방식은 Array 키워드 + 대괄호([])를 사용해서 선언한다. + +### 튜플 타입도 대괄호로 선언한다는 점을 기억하자! + +타입스크립트 튜플 타입은 배열과 유사하지만 튜플의 대괄호 내부에는 **선언 시점에 지정해준 타입 값만 할당**할 수 있다. + +원소 개수도 타입 선언 시점에 미리 정해진다. 이것은 객체 리터럴에서 선언하지 않은 속성을 할당하거나 선언한 속성을 할당하지 않을 떄 에러가 발생하는 것과 같다. + +```ts +const myNames: ["CHU", "SEULGI"] = ["CHU", "SEULGI", "LESLEY"]; // "LESLEY"는 지정할 수 없다. +``` + +
+
+ +## 4) type과 interface + +object 타입은 실무에서 잘 쓰이지 않는다. 객체를 타이핑하기 위해서는 타입스크립트에서만 독자적으로 쓰이는 키워드를 사용하는 게 일반적이다. + +### 그것이 바로 type, interface! + +중복적인 요소가 많은 객체 리터럴 방식으로 타입을 매번 일일이 지정하기에는 중복적인 요소가 많기에 type, interface로 중복 없이 해당 타입을 쓸 수 있다. + +타입스크립트에서는 일반적으로 변수 타입을 명시적으로 선언하지 않아도 컴파일러가 자동으로 타입을 추론하는데, 타입스크립트 컴파일러는 **변수 사용 방식과 할당된 값의 타입을 분석해서 타입을 유추**한다. + +
+ +> **같이 고민해보면 좋을 요소들!**
+> 언제 type, interface를 활용할까? 배민팀들을 보고 더 파보자! + +
+
+ +## 5) function + +typeof 연산자로 함수 타입을 출력해보면 자바스크립트는 함수를 function이라는 별도 타입으로 분류한다. + +```ts +function add(a: number, b: number): number { + return a + b; +} + +console.log(typeof add); // function +``` + +- 타입스크립트도 함수를 별도 함수 타입으로 지정 가능하다. + +### 함수 타입 지정 시 주의할 점을 알아보자! + +1. 자바스크립트에서 typeof 연산자로 확인한 function이라는 키워드 자체를 타입으로 사용하지 않는다. +2. 함수는 매개변수 목록을 받을 수 있는데 타입스크립트에서는 매개변수도 별도 타입으로 지정해야 한다. +3. 함수가 반환하는 값이 있다면 함수 반환 값에 대한 타이핑도 필요하다. + +### 함수 자체의 타입은 어떻게 지정할 수 있을까? + +호출 시그니처를 정의하는 방식으로 사용하면 된다. 호출 시그니처는 함수의 매개변수와 반환 값의 타입을 명시하는 역할을 한다. + +> **호출 시그니처(Call Signature)?**
+> 타입스크립트에서 함수 타입을 정의할 떄 사용하는 문법으로 함수 타입은 해당 함수가 받는 매개변수와 반환하는 값의 타입으로 결정된다. + +```ts +type add = (a: number, b: number) => number; +``` + +- 호출 시그니처는 자바스크립트의 화살표 함수와 맥락이 유사하다. +- 호출 시그니처는 화살표 함수 방식으로만 정의한다. diff --git a/assets/CH02/item_2_example_1.jpeg b/assets/CH02/item_2_example_1.jpeg new file mode 100644 index 0000000..7ee3471 Binary files /dev/null and b/assets/CH02/item_2_example_1.jpeg differ diff --git a/assets/CH02/item_2_example_2.jpeg b/assets/CH02/item_2_example_2.jpeg new file mode 100644 index 0000000..1c2976c Binary files /dev/null and b/assets/CH02/item_2_example_2.jpeg differ