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/seongho.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/seongho.md" new file mode 100644 index 0000000..e8ebb5a --- /dev/null +++ "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/seongho.md" @@ -0,0 +1,55 @@ +## 자바스크립트 & ECMAScript의 탄생 + +90년대에는 넷스케이프의 `내비게이터`와 마이크로소프트의 `인터넷 익스플로러`가 가장 대중적으로 사용되던 브라우저 였음.
+그리고, 1995년에 넷스케이프의 브랜든 아이큰은 웹의 다양한 콘텐츠를 표현하기 위한 언어인 자바스크립트를 만들었음.
+이에 넷스케이프의 경쟁사였던 마이크로소프트도 자바스크립트에 대항하기 위해서 Jscript라는 자바의 파생 언어를 만들었고, 이에 따라서 경쟁관계였던 두 회사는 자신들의 브라우저에 새로운 기능을 빠르게 늘리기 시작했지만 +이렇게 추가된 기능은 각자의 브라우저에서만 동작했음.
+ +특히 익스플로러와 내비게이터는 DOM구조가 완전히 달랐기 때문에 같은 코드라고 할지라도 브라우저 마다 다르게 동작하는 **_크로스 브라우징 이슈_** 가 발생했음.. +그래서 개발자들은 브라우저마다 다른 언어를 사용해서 코드를 짜야하는 불편함이 있었음. + +또한 자바스크립트에 새로운 기능이 추가되도 브라우저가 해당 기능을 지원해야 했고, 새로운 버전의 브라우저가 나온다고 해도 사용자가 이전 버전의 브라우저를 쓰면 무용지물이 되버렸음.
+이런 문제를 해결하기 위해서 `폴리필`과 `트랜스파일`이라는 개념이 등장하게 됨. + +> [!NOTE] > **폴리필과 트랜스파일** +> +>

폴리필은 브라우저가 지원하지 않는 코드를 브라우저에서 사용할 수 있도록 변환한 코드 조각이나 플러그인을 말함.
+> 트랜스파일은 최신 버전의 코드를 예전 버전의 코드로 바꿔주는 역할을 함 (babel)

+ +이러니 `jQuery`같은 브라우저 호환성을 고민하지 않고 한번에 개발 가능한 라이브러리가 유행한것은 당연한 결과인것. +이후 결국엔 `ECMAScript`라는 국제 표준화가 되었음. + +
+ +## 웹의 발전과 개발 생태계의 발전 + +`웹사이트`와 `웹 애플리케이션`의 차이는 뭘까
+ +- `웹 사이트`
+ 컨텐츠를 특정 페이지에 표시하기 위한 정적인 웹 으로써 단방향으로 정보를 제공하기 때문에 사용자와의 상호 작용하지 않으며, 컨텐츠가 동적으로 업데이트 되지 않음. + +- `웹 애플리케이션`
+ 사용자와 상호작용하는 쌍방향 소통의 웹을 말함.
+ 검색, 댓글, 채팅, 좋아요 등등 웹 페이지 내부에 많은 어플리케이션들이 동작하고 있어서 웹 애플리케이션이라고 함. + +이처럼 웹은 점점 발전했고, 일방적으로 컨텐츠를 보여주는 웹 사이트를 넘어서 웹 애플리케이션이 등장함에 따라 개발 환경도 변화하게 된다. + +웹 서비스가 대규모로 커지면서 웹페이지를 통으로 개발하는 방식이아닌, 컴포넌트 단위로 개발을 하게 되는 방식인 `CBD`가 등장하게 됨. +CBD는 서비스에서 다루는 데이터를 구분하고 그에 맞는 UI를 표현할수있게 컴포넌트 단위로 개발하는 접근 방식임. + +> [!Note] > **CBD** +> +>

재사용할수 있는 컴포넌트를 개발 또는 조합해서 하나의 애플리케이션을 만드는 개발 방법론

+ +
+ +`컴포넌트`는 모듈과 유사하게 하나의 독립된 기능을 재사용하기 위한 코드 묶음임.
+컴포넌트는 다른 컴포넌트와의 의존성을 최소화 하거나 없애는게 좋은데, 개발 과정에서 필연적으로 의존성은 생길수밖에 없음. +따라서 개발자는 **_컴포넌트 간의 의존성을 파악해야 제대로 컴포넌트를 사용하고, 유지보수 하기에 용이함._** + +또 이런 개발 생태계의 발전은 JS개발자의 증가로 이어졌고, 협업의 필요성이 대두되는 계기가 되었다. + +개발에 투입된 인원이 많아질수록 코드를 파악하기 어려워지는 것은 당연한 수순이다. +다른 동료가 작성한 코드를 사용할때마다 작성자에게 가서 물어보는 것은 너무나도 큰 코스트가 들게되고, 이마저도 작성자가 회사에 남아있어야 가능함.
+따라서 유지보수를 위한 효과적인 협업 보완책이 필요해졌음.
+그렇다면 JS는 과연 유지보수에 적합한 언어였을까? 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/seongho.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/seongho.md" new file mode 100644 index 0000000..f64f80d --- /dev/null +++ "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/seongho.md" @@ -0,0 +1,45 @@ +## 자바스크립트의 한계 +JS의 특징은 `동적 타입 언어` 라는것이다.
+이는 **변수에 타입을 명시적으로 지정하지 않고, 코드가 실행되는 런타임에 변숫값이 할당될 때 해당 값의 타입에 따라 변수 타입이 결정된다는 것.** + +아래 코드를 봐보자 +```js +const sumNumber = (a, b) => { + return a + b; +}; + +sumNumber(1, 2); // 3 +sumNumber(100); // NaN +sumNumber('a', 'b'); // 'ab' +``` +여기서 주목해야 하는 점은 함수를 실행할 때 인자에 하나의 숫자만 전달하거나, 숫자가 아닌 문자를 전달했다는 점인데, 어떤 에러도 없이 정상적으로 동작함. + +이는 개발자의 의도와는 다르게 동작할 수 있음을 뜻함. +그런데도 JS엔진은 해당 코드를 문제없이 실행시켜 버림. 왜냐하면 JS가 동적 타입 언어이기 때문임. js엔진 입장에서는 주석, 함수이름, 개발자 의도 같은것들은 고려대상이 아닌 것.
+그렇다면 개발자들은 이런 문제를 어떻게 해결하려고 했을까?? + +개발자들은 이러한 문제로 골머리를 썩었고, js의 인터페이스의 필요성을 느끼게 됨.
+따라서 `JSDoc`, `PropTypes`, `다트`와 같은 해결방안이 등장하게 되었음. +모두 좋은 방안이었지만 **_"자바스크립트가 스스로 인터페이스를 기술할 수 있는 언어로 진화해야 한다!"_** 라는 목소리는 점점 더 켜졌다. + +
+ +## 타입스크립트의 등장 +마이크로소프트는 js의 수퍼셋 언어인 `타입스크립트(ts)`를 공개했다. +`다트`와 달리 js코드를 그대로 사용할 수 있었고, 아래와 같은 단점을 극복할 수 있었음. + +> [!NOTE] +> **슈퍼셋** +>

기존 언어에 새로운 기능과 문법을 추가해서 보완하거나, 상향하는 것을 말함.

+ +1. **안정성 향상**
+ts는 정적타이핑을 제공함으로써 컴파일 단계에서 타입 검사를 해주기 때문에 js를 사용했을 때 빈번하게 발생하는 타입 에러를 줄일 수 있고, 런타임 에러를 사전에 방지할 수 있어서 안정성이 크게 높아짐. + +2. **개발 생산성 향상**
+변수와 함수 타입을 추론할 수 있고, 리액트를 사용할떄 어떤 prop을 넘겨야 하는지 매번 확인하지 않아도 바로 볼 수 있어서 개발 생산성이 크기 높아짐. + +3. **협업에 유리**
+자동완성 기능이나, 기술된 인터페이스를 활용하여 코드를 쉽게 파악할 수 있음. + +4. **js에 점진적으로 적용 가능**
+ts는 js의 슈퍼셋 언어이기 때문에 일부만 적용해도 문제없이 작동이 가능함. diff --git "a/CH02_\355\203\200\354\236\205/2.1_\355\203\200\354\236\205\354\235\264\353\236\200/seongho.md" "b/CH02_\355\203\200\354\236\205/2.1_\355\203\200\354\236\205\354\235\264\353\236\200/seongho.md" index 3beced8..6859621 100644 --- "a/CH02_\355\203\200\354\236\205/2.1_\355\203\200\354\236\205\354\235\264\353\236\200/seongho.md" +++ "b/CH02_\355\203\200\354\236\205/2.1_\355\203\200\354\236\205\354\235\264\353\236\200/seongho.md" @@ -1 +1,122 @@ - +## 자료형으로서의 타입 +프로그래밍 언어에서 변수란 값을 저장할 수 있는 공간이자 값을 가리키는 이름임. +개발자는 변수를 선언하고 그 변수에 특정 값인 데이터를 할당함. + +컴퓨터의 메모리 공간은 한정적임. +따라서 특정 메모리에 값을 효율적으로 저장하려면 값의 크기를 알아야 함. +개발자는 타입을 사용해서 값의 종류는 명시할 수 있고, 메모리를 더욱 효율적으로 사용 가능함.
+ECMAScript에 표준을 따르는 js의 타입에는 **7가지 데이터 타입(자료형)** 이 있음. +- `undefined` +- `null` +- `Boolean` +- `String` +- `Numeric (Number와 BigInt)` +- `Object` +- `Symbol` + +
+ +## 집합으로서의 타입 +프로그래밍에서 타입은 수학의 집합과 유사함. 타입은 값이 가질 수 있는 범위의 집합을 말함. + +```ts +const num: number = 123; +const str: string = 'abc'; + +function func(n: string) { + // ... +} + +func(num); // error! +func(str); +``` + +어떤 값이 T라는 타입이라면 컴파일러나 개발자는 이 값으로 어떤일을 할 수 있고, 어떤 일을 할 수 없는지를 사전에 알수 있음. +위 예시는 마치 집합의 경계처럼 func함수의 인자로 들어갈 수 있는 값을 number타입의 집합으로 제한 하는것임. + +```js +function doule(n) { + return n * 2; +} + +double('a'); // NaN +``` +해당 코드를 보면 개발자는 숫자를 인자로 받을 것 이라고 기대하지만, 의도치 않은 상황이 발생할 수도 있음. +이때 ts로 타입을 제한하게 되면, 올바르지 않은 값이 들어왔을 경우 에러를 발생시킴. + +```ts +function doule(n: number) { + return n * 2; +} + +double('a'); // error! +``` + +
+ +## 정적 타입과 동적 타입 +자바스크립트에도 분명히 타입은 존재함. +다만, 컴파일 이전에 개발자가 직접 타입을 결정해주지 않아도 될 뿐임.
+이처럼 타입을 결정하는 시점에 따라서 타입을 `정적 타입`과 `동적 타입`으로 구분이 가능함. + +- `정적 타입 시스템`
+ 1. 변수의 타입이 컴파일 타임에 결정됨. + 2. 코드 수준에서 개발자가 타입을 명시해줘야 함. + 3. 컴파일 타임에 에러를 발견할 수 있어서 **프로그램의 안정성을 보장**할 수 있음
+ `자바` `C`, `C++`, `ts` + +- `동적 타입 시스템`
+ 1. 변수 타입이 런타임에서 결정 됨. + 2. 개발자가 직접 타입을 정의해줄 필요가 없음. + 3. **프로그램의 안정성을 보장할 수 없음.**
+ `파이썬`, `js` + +> [!NOTE] +> **컴파일 타임과 런타임**
+> 고급 언어로 작성된 프로그래밍 언어(소스코드)가 기계어로 변환되는 시점을 컴파일 타임이라고 하며, 이후 변환된 파일이 메모리에 적재되어 실행되는 시점을 런타임이라고 함. + +
+ +## 강타입과 약타입 +개발자가 타입을 명시하거나, 바꾸지 않았는데도 컴파일러 또는 엔진에 의해서 런타임에 타입이 자동으로 변경되는 것을 `암묵적인 형 변환` 이라고 함.
+이러한 `암묵적인 형 변환`의 여부에 따라서 타입 시스템을 `강타입`과 `약타입`으로 나눌 수 있음. +- `강타입`
+서로 다른 타입을 갖는 연산을 시도하면 컴파일러 또는 인터프리터에서 에러가 발생함. + +- `약타입`
+서로다른 타입을 갖는 값끼리 연산을 할때는 컴파일러 또는 인터프리터가 내부적으로 판단해서 특정 값의 타입을 변환시킨 뒤, 연산을 수행함. + +```python +# 파이썬 +print('2' - 1) # error! +``` +```js +// js +console.log('2' - 1); // 1 +``` +```ts +// ts +console.log('2' - 1); // type error! +``` + +예시처럼 `c++`, `자바`, `js`에서는 **암묵적인 형 변환**이 발생함. +이에 반해 `루비`, `파이썬`, `ts`에서는 타입 에러가 발생한다. +결론적으로 `c++`, `자바`, `js`는 **_약타입 언어_** 로, `루비`, `파이썬`, `ts`는 **_강타입 언어_** 로 분류할 수 있음.
+js는 `약타입 언어`이기때문에 런타임에서 발생할 수 있는 에러를 예측하고, 방지할 수 있는 코드를 작성하는 게 프로그램의 안정성 측면에서 도움이 됨. + +`타입 시스템`
+-> 타입 검사기가 프로그램에 타입을 할당하는 데 사용하는 규칙 집합 +타입 시스템은 크게 두가지로 구분 됨. +1. 어떤 타입을 사용하는지를 컴파일러에게 명시적으로 알려줘야 하는 타입 시스템 +2. 자동으로 타입을 추론하는 타입 시스템 + +ts는 두가지 시스템의 영향을 모두 받았기 때문에, 두가지의 방식중에 선택할 수 있음. + +
+ +## 컴파일 방식 +`컴파일`이란 보통, 사람이 이해할 수 있는 방식으로 작성한 코드를 컴퓨터가 이해할 수 있는 기계어로 바꿔주는 과정을 말함(고급언어 -> 기계어). 즉 개발자가 js로 코드를 작성하면 컴파일러는 0과 1로 이루어진 `바이너리 코드`로 변환시킴.
+이처럼 `컴파일`은 기본적으로 서로 다른 수준 간의 코드 변환을 의미함. + +**근데 ts는 컴파일을 하면 타입이 모두 제거된 js코드만 남게 됨.** +이러한 이유 때문에 ts를 js에 **타입이라는 레이어**를 끼얹은 일종의 `템플릿 언어`또는 `확장 언어`라고 말하는 사람들도 있음. \ No newline at end of file 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/seongho.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/seongho.md" index 3beced8..b28cb50 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/seongho.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/seongho.md" @@ -1 +1,486 @@ - +## 타입 애너테이션 방식 +`타입에너테이션`
+-> 변수나 상수 혹은 함수의 인자와 반환값에 타입을 명시적으로 선언해서 어떤 타입 값이 저장될지 컴파일러에게 알려주는 문법. + +타입스크립트는 변수 이름 뒤에 `: type` 구문을 붙여서 데이터 타입을 명시함. +```ts +const name: string = 'seongho'; +const age: number = '27'; +const list: number[]: [1, 2, 3]; +``` +ts는 기존 js코드에 점진적으로 타입을 적용할 수 있는 특징이 있어서 `: type` 구문을 제거해도 정상적으로 동작함.
+하지만 타입을 제거하면 ts의 타입 시스템이 타입을 추론하는 과정에서 어려움을 겪음;
+ +
+ +## 구조적 타이핑 +타입을 사용하는 어러 언어에서는 어떤 값이나 객체는 하나의 구체적인 타입을 가지고 있음. +타입은 이름으로 구분되며, 컴파일 이후에도 남아있음.
+또한 서로 다른 클래스끼리 명확한 상속관계나 공통으로 가지고 있는 인터페이스가 없다면 타입은 서로 호환되지 않음.
+이것을 `명목적으로 구체화 한 타입 시스템`이라고 부르기도 함 + +근데 타입스크립트에서는 조금 다름. +타입스크립트는 이름으로 타입을 구분하는 명목적인 타입 언어와는 다르게 구조로 타입을 구분함.
+이를 `구조적 타이핑`이라고 함. + +```ts +interface Man { + name: string; +} + +interface Woman { + name: string; +} + +let boy: Man = { name: 'seongho' }; +let girl: Woman = { name: 'seulgi' }; + +boy = girl; // ✅ +girl = boy; // ✅ +``` + +
+ +## 구조적 서브 타이핑 +타입스크립트의 타입 시스템은 집합으로 이해할수 있다고 했는데, 이처럼 타입은 단지 집합에 포함되는 값이고 특정 값은 많은 집합에 포함될 수 있음.
+따라서 타입스크립트에서는 특정 값이 `string` 또는 `number`타입을 동시에 가질 수 있음. +```ts +type StringOrNumber = string | number; +``` + +이처럼 집합으로 나타낼 수 있는 타입스크립트의 타입 시스템을 지탱하고 있는 개념이 바로 `구조적 서브타이핑` 임.
+**`구조적 서브타이핑`이란 객체가 가지고 있는 프로퍼티를 바탕으로 타입을 구분하는 것으로, 이름이 다른 객체라도 가진 프로퍼티가 동일하면 ts는 서로 호환이 가능한 동일한 타입으로 여긴다는 것임.** + +
+ +```ts +interface Pet { + name: string; +} + +interface Dog { + name: string; + age: number; +} + +let pet: Pet; +let dog: Dog = { name: '도크', age: 4 }; + +pet = dog; // ✅ +``` +**Pet**과 **Dog**는 서로 다른 타입으로 선언됬지만, **Pet**이 갖고있는 name이라는 프로퍼티를 **Dog**이 갖고있음.
+따라서 **Dog**타입으로 선언한 **dog**를 **Pet**타입으로 선언한 **pet**에 할당이 가능함. + +이러한 개념은 매개변수에도 적용됨 +```ts +interface Dog { + name: string; + age: number; +} + +interface Pet { + name: string; +} + +const dog: Dog = { name:'무개력', age: 4 }; + +function getPetName(pet: Pet) { + return pet.name; +} + +getPetName(dog); // ✅ +``` +이게 가능한 이유는 **dog**객체는 **Pet**인터페이스가 갖고있는 **name**이라는 속성을 갖고 있어서 **pet.name**의 방식으로 name에 접근이 가능하기 떄문임.
+이런 방식이 바로 `구조적 타이핑`임. 또다른 예시를 보자면 + +
+ +```ts +class Person { + name: string; + age: number; + + constructor(name: string, age: number) { + this.name = name; + this.age = age; + } +} + +class Developer { + name: string; + age: number; + language: string; + + constructor(name: string, age: number, language: string) { + this.name = name; + this.age = age; + this.language = language + } +} + +function foo(person: Person) { + // ... +} + +const dev: Developer = { name: 'seongho', age: 27, language: 'ts' }; + +foo(dev); // ✅ +``` +**Developer**클래스는 **Person**클래스는 상속받지 않았음에도 불구하고 `foo(dev)`가 에러 없이 정상적으로 동작함. +**Developer**클래스는 **Person**클래스가 갖고있는 모든 속성을 갖고있기 때문임. + +**_이처럼 타입스크립트는 서로 다른 타입간의 호환성은 오로지 타입 내부의 구조에 의해서 결정됨._**
+따라서 타입이 계층 구조로부터 자유롭다는 특징이 있음. + +
+ +## 자바스크립트를 닮은 타입스크립트 +ts는 `구조적 서브타이핑`을 사용함. 이는 타입의 구조가 아닌 타입의 이름으로 구분을 하는 `명목적 타이핑`과는 대조되는 개념임. +```java +// Java +class Cat { + String name; + public void hit() {} +} + +Class Arrow { + String name; + public void hit() {} +} + +public class Main { + public static void main(String[] args) { + Arrow cat = new Cat(); // Error! + + Cat arrow = new Arrow(); // Error! + } +} +``` +-> ts에서는 가능한 코드가 명목적 타이핑을 사용하는 Java에서는 불가능함. +**이는 객체의 속성을 다른 객체의 속성과 호환되지 않도록 하여 안정성을 추구함.** + +그런데도 ts는 왜 `구조적 서브타이핑`을 채택했을까?
+그거는 js가 본질적으로 **덕 타이핑**을 기반으로 하기 때문이고, ts는 js를 모델링한 언어이기 때문임.
+ +**_`덕 타이핑`이란 어떤 함수의 매개변숫값이 올바르게 주어진다면 그 값이 어떻게 만들어졌는지 신경쓰지 않고 사용한다는 개념임._** +ts는 이런 js의 `덕 타이핑` 방식을 그대로 받아들여서 이름을 가지고 타입을 구분하는게 아니라, 구조적 특징을 기반으로 타이핑 하는 방식을 채택한 것. + +그렇다면 `덕 타이핑`과 `구조적 서브타이핑`의 차이는 무엇일까? 그 차이점은 타입을 검사하는 시점에 있음. + +- **덕 타이핑**
+런타임에 타입을 검사함 + +
+ +- **구조적 타이핑**
+컴파일 타임에 타임 체계가 타입을 검사함. + +> [!NOTE] +> **_덕 타이핑_**
+> 어떤 타입에 부합하는 변수와 메서드를 가질 경우, 해당 타입에 속하는 것으로 간주하는 방식.
+> _**'만약, 어떤 새가 오리처럼 걷고, 헤엄치며 꽥꽥거리는 소리를 낸다면 나는 그 새를 오리라고 부를것이다.'**_ + +
+ +## 구조적 타이핑의 결과 +근데 이런 유연함 때문에 예기치 못한 결과가 나오기도 함 +```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; + } +} +``` +왜 이럴까?
+이는 ts가 구조적 타이핑의 성격을 띄기 때문에, `Cube`의 `width`, `height`, `depth`이외에도 어떤 속성이든 갖고있을 수 있어서 `c[axis]`의 타입이 `number`가 아닌 다른것일 수도 있어서 에러가 발생하는 것. +```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; + } +} + +addLines({ + width: 10, + height: 10, + depth: 10, + name: 'cube' +}); // OK +``` +이런 거지
+ +이런 한계를 극복하기 위해서 ts는 `유니온` 같은 방법이 생겼음. + +
+ +## 타입스크립트의 점진적 타입 확인 +ts는 점진적으로 타입을 확인하는 언어임. +`점진적 타입 검사`란 **_컴파일 타임에 타입을 검사하면서 필요에 따라 타입 선언 생략을 허용하는 방식._** +타입 어노테이션 방식으로 지정해주면 정적으로 타입을 검사하지만 타입 선언이 생략되면 동적으로 타입 검사를 수행함.
+타입 선언을 생략하면 암시적인 타입 변환이 일어남 +```ts +function add(x, y) { + return x + y; +} +``` +이렇게 적으면 ts는 아래처럼 타입을 암시적으로 변환시킴 +```ts +function add(x: any, y: any): any; +``` +타입을 명시하지 않아서 ts는 모두 `any`타입으로 추론하는 것임.
+이처럼 ts는 필요에 따라서 타입을 생략할 수 있는데, 이를 ts가 갖고있는 `점진적 타이핑` 이라고 하는 특징임. 이를 활용해서 `js`에서 `ts`로 마이그레이션 할때 점진적으로 진핼할 수 있는 것. + +> [!NOTE] +> **_any 타입_**
+> ts의 모든 타입을 포함하는 가장 상위 타입으로, 어떤 값이든 할당할 수 있음.
+> `tsconfig`의 `noImplicitAny`를 `true`로 켜두면 타입 애너테이션이 없을때 ts가 암묵적으로 `any`로 추론하는 것을 허락하지 않을 수 있음. + +
+ +## 자바스크립트의 슈퍼셋으로서의 타입스크립트 +ts는 기존의 js코드에 정적인 타이핑을 추가한 것으로 js의 상위집합임.
+따라서 모든 js코드는 ts지만, 모든 ts가 js인것은 아님. +```ts +// ts +function add(x: number, y: number): number { + return x + y; +} + +// js +function add(x: number, y: number): number { + return x + y; +} // Error! +``` + +
+ +## 값 vs 타입 +`값` 이란?
+-> 프로그램이 처리하기 위해 메모리에 저장하는 모든 데이터.
+어떤한 식을 연산한 것으로 변수에 할당할 수 있음. +```ts +11; // 값 +'hello world'; // 값 +const foo = 'bar'; // 값 +const getName = function (name) { + return name; +} // js에서는 함수도 값임. +``` + +
+ +ts에 들어오면서 **'타입'** 이라는 개념이 등장함. +ts는 변수, 매개변수, 객체 속성 등에 `: type`으로 타입을 명시함.
+```ts +const a: string = 'name'; +const b: number = 12; +... +``` +또는 `type`이나 `interface` 키워드로 커스텀 타입을 정의할 수 있음. +```ts +interface Person { + name: string; + age: number; +} + +type Person = { + name: string; + age: number; +}; +``` +ts는 컴파일을 하게 되면 타입 관련 부분들에 전부 제거되고, js파일만 남게 되기 때문에 +**_값 공간_**과 **_타입 공간_**은 서로 충돌하지 않음. 이러한 특징 때문에 타입과 변수를 같은 이름으로 지어도 문제가 되지 않음. + +보통 타입과 값을 구분하는 것은 어렵지 않음. 값은 `=` 으로, 타입은 `:` 또는 `as`로 작성함. +```ts +interface Developer { + name: string; + isWorking: boolean; +} + +const developer: Developer = { name: 'seongho', isWorking: true }; +``` +-> 여기서 `Developer`는 타입, `{ name: 'seongho', isWorking: true }`는 값임. + +```ts +function information(name: string, age: number) { + // ... +} +``` + +
+ +근데 ts는 값과 타입의 구분은 맥락에 따라서 달라지기 때문에 값공간과 타입 공간을 혼동할때가 있는데, 이를 주의해야 함. +js의 Destructuring을 사용하면 객체를 풀어서 받을 수 있음 +```ts +// js +function information({ person, name, age }) { + // ... +} +``` +근데 같은 코드를 ts에서 쓰면 오류가 발생함. +```ts +function information({ + person: Person + string, + string, +}) { + // ... +} +``` +
+ +이는 값의 관점에서 `Person`과 `string`이 해석됬기 때문임.
+개발자의 의도는 `person`을 `Person`타입으로, `name`과 `age`를 `string`타입으로 설정하려고 했으나 `Person`과 `string`이 값 공간에 있는 것으로 해석됬기 때문임. +따라서 ts에서는 위 코드와 같은 값-타입 공간을 혼동하는 문제를 해결하기 위해 값과 타입을 구분해서 작성해야 함. +```ts +function information({ + person, + name, + age +}: { + person: Person; + name: string; + age: string; +}) { + // ... +} +``` + +
+ +## class와 enum +ts에서는 값과 타입 공간이 동시에 존재하는 심볼도 있음.
+대표적으로 `class`와 `enum`이 있음. 클래스는 인스턴스 객체를 쉽게 생성하기 위한 문법으로 실제 동작은 생성자 함수와 같음.`(syntantic sugar)`
+그와 동시에 클래스는 타입으로도 사용 됨 +```ts +class Seongho { + name: string; + age: number; + + constructor(name: string, age: number) { + this.name = name; + this.age = age; + } +} + +const instanceSeongho: Seongho = new Seongho('인스턴스 성호', 5); +``` +-> 여기서 `Seongho는` **타입**으로도 사용되고, 생성자 함수인 **값**으로도 사용 되었음. + + + +클래스를 작성할 경우 클래스 내부 타입 선언과, 넘겨줄 인자의 타입은 동일해야 한다는 점 (어찌보면 당연한 말이지만..) + +
+ +클래스와 마찬가지로 `enum`또한 런타임에 객체로 변환됨. enum은 ts에서 제공하는 기능으로, js에 존재하지는 않음. +enum으로 작성한 코드를 컴파일 하면 +```js +var Seongho; +(function (Seongho) { + Seongho[Seongho["name"] = 0] = "name"; + Seongho[Seongho["age"] = 1] = "age"; + Seongho[Seongho["location"] = 2] = "location"; +})(Seongho || (Seongho = {})); +``` +이러한 형태가 됨. +`enum`도 클래스와 동일하게 js런타임에서 실제 값으로 사용될 수 있음.
+예시를 봐보자 + +
+ +```ts +enum UserResponse { + No = 0, + Yes = 1, +} + +function getResponse(res: { Yes: number }) { + return res; +} + +getResponse(UserResponse); +``` +
+ +#### 타입스크립트에서 자바스크립트의 키워드가 해석되는 방식 + +|키워드|값|타입| +|----|--|---| +|`class`|Y|N| +|`const` `let`, `var`|Y|N| +|`enum`|Y|Y| +|`function`|Y|N| +|`interface`|N|Y| +|`type`|N|Y| +|`namespace`|Y|N| + +
+ +## 타입을 확인하는 방법 +ts에서는 `typeof`, `instanceof`, `타입 단언`을 활용해서 타입을 확인할 수 있음. +- `typeof`
+ 7가지 기본 데이터 타입, Function, 호스트 객체, object객체가 될 수 있음
+ ```ts + typeof 2022; // number + typeof 'abc'; // string; + typeof {}; // object + ``` + +**_근데 주의할 점은 `typeof`연산자는 값에서 쓰일때와 타입에서 쓰일때의 역할이 다름._** +- `값에서 사용된 typeof`는 js런타임의 `typeof`로 사용됨. (js의 typeof연산자로 사용된다는 뜻) + 2장 typeof 이미지
+ -> 요놈
+
+ ```ts + interface Person { + name: string; + } + const person = new Person('seongho'); + const func = () => {}; + + const v1 = typeof person; // 'object' + const v2 = typeof func; // 'function' + ``` +- `타입에서 사용된 typeof`는 값을 읽고 ts의 타입을 반환함. + ```ts + type t1 = typeof person; // Person + type t2 = typeof func; // () => void + ``` + `person`은 변수가 `Person`타입으로 선언되었기 때문에 **_타입 공간에서의 `typeof person`은 `Person`을 반환함._**
+ `func`는 **_타입 공간에서 `typeof`로 값을 읽으면 `함수 시그니처 타입`을 반환함._** + +
+ +ts에서는 `타입 단언`이라고 부르는 문법을 통해서 타입을 강제할 수도 있음. `as`키워드를 사용하면 됨 +```ts +const num: number; + +function getString(str: string) { + // ... +} + +getString(num as string); +``` +-> num은 number타입이지만 string으로 `타입 단언`을 시켜서 getString의 인자로 넘겨줌.. \ No newline at end of file diff --git "a/CH02_\355\203\200\354\236\205/2.3_\354\233\220\354\213\234_\355\203\200\354\236\205/seongho.md" "b/CH02_\355\203\200\354\236\205/2.3_\354\233\220\354\213\234_\355\203\200\354\236\205/seongho.md" index 3beced8..3ba7fbc 100644 --- "a/CH02_\355\203\200\354\236\205/2.3_\354\233\220\354\213\234_\355\203\200\354\236\205/seongho.md" +++ "b/CH02_\355\203\200\354\236\205/2.3_\354\233\220\354\213\234_\355\203\200\354\236\205/seongho.md" @@ -1 +1,106 @@ - +## 원시 타입 +자바스크립트의 7가지 원시 값은 타입스크립트에서 원시 타입으로 존재함. + +> [!NOTE] +> **_원시 값과 원시 래퍼 객체_**
+> js의 내장타입은 Pascal표기법으로 표기했음. 반면에 ts에서는 타입을 소문자로 표기함
+> 타입을 Pascal표기법으로 표시하면 js에서 이것을 원시 래퍼 객체라고 인식함. + +
+ +### 1. `boolean` +```ts +const isEmpty: boolean = true; +const isLoading: boolean = false; + +function isTextError(errorCode: errorCodeType): boolean { + const errorAction = getErrorAction(erroCode); + + if (errorAction) { + return errorAction.type === ERROR_TEXT; + } + + return false; +} +``` +오직 `true`와 `false`만 할당 가능한 `boolean`타입. js에서는 원시값은 아니지만 형 변환을 통해 true / false로 취급되는 `truthy`, `falsy`값이 존재하는데, 이들은 엄연히 `boolean`타입이 아님. + +
+ +### 2. `undefined`
+```ts +let name: string; + +type Person = { + name: string; + age?: number; +} +``` +정의되지 않았다는 의미의 타입으로 오직 `undefined`만 할당할 수 있는 타입.
+`Person`타입의 `age`속성은 옵셔널로 지정되어져 있는데, 이런 경우에도 `undefined`를 할당할 수 있음. + +
+ +### 3. `null` +```ts +let value: null; + +value = null; +``` +오직 `null`만 할당가능한 타입으로 `undefined`와 혼동하면 안됨.
+비슷해 보여도 엄연히 따로 존재하는 원시 값이기 때문에 서로의 타입에 할당할 수 없음. `undefined`는 값이 있을수도 있고, 없을수도 있음을 나타내기도 하지만, `null`은 명시적으로 값이 없다고 알려주는 의미가 강함. + +
+ +### 4. `number` +```ts +const age: number = 27; +const min: number = 10; +const max: number = 12; +const infinity: number = +Infinity; +const notANumber: number = NaN; +``` +숫자에 해당하는 모든 원시값을 할당할 수 있는 타입.
+Java와 같은 언어에서는 `byte`, `short`, `int`, `long`, `double`, `float등` 다양한 숫자 타입으로 구분되어져 있지만 js는 정수, 부동소수점을 구분하지 않기때문에 모두 `number`타입에 할당할 수 있음.
+ +> [!CAUTION] +> **`NaN`이나 `Infinity`도 포함된다는 것에 주의하자** + +
+ +### 5. `bigInt` +```ts +const bigNumber: bigInt = BigInt(9999999999); +const bigNumber2: bigInt = 9999999999999n; +``` +`ES2020`부터 도입된 데이터 타입으로 **ts 3.2버전**부터 사용이 가능함.
+`number`타입과는 엄연히 다른 타입이므로 호환은 불가능함. + +
+ +### 6. `string` +```ts +const name: string = 'seongho'; +const location: sting = 'goyang'; +``` +문자열을 할당할 수 있는 타입으로, 공백도 `string`타입에 해당 함. + +
+ +### 7. `symbol` +```ts +const TITLE: symbol = Symbol('TITLE'); +const TITLE2: symbol = Symbol('TITLE'); + +TITLE === TITLE2; // false +``` +`ES2015`부터 도입된 데이터 타입으로 `Symbol()`을 사용하면 어떤 값과도 중복되지 않는 유일한 값을 생성할 수 있음.
+예시처럼 동일한 문자열을 넘겨줬음에도 불구하고, 다른 값을 갖고있음. ts에는 `symbol`과 `const`선언에서만 사용 가능한 `unique symbol`타입이라는 symbol의 하위타입도 존재함. + +
+ +ts에서 `number`, `string`, `boolean`은 가장 많이 사용되면서 사용자에 따라서 다르게 사용될 여지가 적은 반면, `null`이나 `undefined`는 사용자에 따라서 다르게 사용될 여지가 많음.
+따라서 tsconfig의 `strictNullChecks`옵션을 활성화 하면 명시적으로 null이나 undefined를 할당해주지 않으면 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/seongho.md" "b/CH02_\355\203\200\354\236\205/2.4_\352\260\235\354\262\264_\355\203\200\354\236\205/seongho.md" index 3beced8..999631a 100644 --- "a/CH02_\355\203\200\354\236\205/2.4_\352\260\235\354\262\264_\355\203\200\354\236\205/seongho.md" +++ "b/CH02_\355\203\200\354\236\205/2.4_\352\260\235\354\262\264_\355\203\200\354\236\205/seongho.md" @@ -1 +1,112 @@ - +## 객체 타입 +앞에서 언급한 7가지 타입에 포함되지 않는 값들은 모두 객체 타입으로 분류할 수 있음. +js에서는 이런 방대한 값들을 모두 `객체`로 퉁치지만, ts에서는 개별적으로 타입을 지정할 수 있음. + +
+ +### 1. `object` +js 객체의 정의에 맞게끔 이에 대응하는 ts의 타입 시스템은 `object`타입임. +그러나 object타입은 가급적 사용하지 말도록 권장 됨. **object는 객체에 해당하는 모든 값들을 할당할 수 있어서 정적 타이핑의 의미가 퇴색되기 때문임.** + +object타입 이미지 + +
+ +### 2. `{}` +객체를 타이핑 할때 사용하는 방식으로, 중괄호 안에 객체의 프로퍼티를 지정해주는 식으로 사용함. +```ts +const obj: { + name: string; age: number; +} = { + name: 'seongho', age: 27, +}; + +const emptyObj: {} = { name: 'seongho' }; // Error! +``` +그냥 `{}`타입으로 타입을 지정하면 해당 객체는 어떤 프로퍼티도 가질 수 없음. 사실 빈 객체 타입을 지정 해줄때는 `{}`보다는 `Record`가 더 권장되는 방식임. + +
+ +### 3. `array` +ts에서는 js의 객체를 세분화 해서 타입을 지정할 수 있는 타입 시스템을 가지고 있다고 했음. +js에서는 객체 외에도 `배열`, `함수`, `정규표현식` 등이 객체 범주에 속함. 그러나 ts에서는 이런 각각의 객체에 타입을 지정할 수 있음.
+js에서는 배열에 원소를 자유롭게 추가/제거 할수 있으며, 타입 제한 없이 다양한 값을 다룸. +```js +const arr = [1, 'srt', () => {}]; +``` +근데 이런 특징은 ts가 추구하는 `정적 타이핑`과는 방향이 맞지 않음.
+ts에서는 배열을 array라고 하는 별도의 타입으로 구분함. ts에서의 array는 하나의 타입 값만 가질 수 있지만, 원소의 갯수는 상관이 없음. +선언하는 방식은 Array키워드로 선언하거나, 대괄호(`[]`)를 사용해서 선언할 수 있음. +```ts +const numArray: number[] = [1, 2, 3, 4, 5]; +const numArray2: number[] = []; // 빈 배열도 가능 +const strArray: Array = ['a', 'b', 'c']; +const strArray2: Array = ['a', 'b', 1]; // Error! +``` + +> [!TIP] +> **튜플 타입**
+> ts에서는 튜플 타입이라는게 존재하고, 튜플 타입 또한 대괄호를 사용해서 선언 함.
+> 튜플은 선언 시점에 지정해준 타입 값을 선언시점에 지정한 원소의 갯수 만큼만 할당할 수 있음
+> ```ts +> const tuple: ['A', 'B'] = ['A', 'B']; +> const tuple2: ['A', 'B'] = ['A', 'B', 'C']; // Error! +> ``` + +
+ +### 4. `type`과 `interface` 키워드 +ts에서 객체를 타이핑 하기 위해서는 ts의 독자적인 키워드를 사용하는게 일반적임. 흔히 객체를 타이핑 하기 위해서 자주 사용되는 키워드는 `type`과 `interface`가 있음. +```ts +type Person = { + name: string; + age: number; +}; + +interface IPerson { + name: string; + age: number; +} + +const person1: Person = { name: 'seongho', age: 27 }; +const person2: IPerson = { name: 'seongho2', age: 27 }; +``` + +
+ +### 5. `function` +js에서는 함수도 객체로 취급하지만, `typeof` 연산자를 통해서 함수는 `function`이라는 별도 타입으로 분류 되는것을 알 수 있음. +```js +typeof function() {}; // 'function' +``` +ts에서도 함수를 별도의 타입으로 지정할 수 있음. 이때 주의할 점이 몇가지 있는데 +1. **js에서 `typeof` 연산자로 확인한 `'function'` 이라는 키워드를 타입으로 사용하지 않는 다는 것.** +2. **매개변수도 별도 타입으로 지정해야 한다는 것.** +3. **함수가 반환하는 값이 있다면 반환값에 대한 타이핑도 필요함.** + +```ts +function add(a: number, b: number): number { + return a + b; +} +``` + +
+ +만약, 함수 자체의 타입을 지정하고 싶다면 `호출 시그니처`를 정의해야 함. +_(타입 영역에서의 `typeof` 키워드로 함수의 타입을 받았을 때 반환하는 것이 `호출 시그니처`임)_ +호출 시그니처 예시 사진 + +
+ +```ts +type Add = (a: number, b: number) => number; // 호출 시그니처 + +const add2:Add = (c, d) => { + return c + d; // ✅ +}; + +const add3: Add = (e, f) => { + return e + "b"; // Error!! +} + +``` diff --git a/assets/CH02/class_1.jpeg b/assets/CH02/class_1.jpeg new file mode 100644 index 0000000..07ab3ae Binary files /dev/null and b/assets/CH02/class_1.jpeg differ diff --git a/assets/CH02/object type.jpeg b/assets/CH02/object type.jpeg new file mode 100644 index 0000000..94bfc79 Binary files /dev/null and b/assets/CH02/object type.jpeg differ diff --git a/assets/CH02/typeof function.jpeg b/assets/CH02/typeof function.jpeg new file mode 100644 index 0000000..8227998 Binary files /dev/null and b/assets/CH02/typeof function.jpeg differ diff --git a/assets/CH02/typeof_mdn.jpeg b/assets/CH02/typeof_mdn.jpeg new file mode 100644 index 0000000..4477aaf Binary files /dev/null and b/assets/CH02/typeof_mdn.jpeg differ