๐ค Chapter 1: ํ์ ์คํฌ๋ฆฝํธ์ ๊ฐ๋ฐ ํ๊ฒฝ ๋ง๋ค๊ธฐ
๐ฆ ํ์ ์คํฌ๋ฆฝํธ๋ ๋ฌด์์ธ๊ฐ?โ
๐ ์๋ฐ์คํฌ๋ฆฝํธ์ ํ์ ๊ธฐ๋ฅ์ด ์์ผ๋ฉด ์ข์ ์ด์ โ
- ์ค๋๋ ์ํํธ์จ์ด๋ ์๋นํ ๋ณต์กํ๋ฏ๋ก ๋ณดํต ์ฌ๋ฌ ์ฌ๋์ด๋ ํ์ด ํ๋ ฅํด ํ๋์ ์ ํ์ ๊ฐ๋ฐํ๋ค.
- ํญ์ ์ฝ๋๋ฅผ ์์ฑํ ์ชฝ๊ณผ ์ฌ์ฉํ๋ ์ชฝ ์ฌ์ด์ ์ปค๋ฎค๋์ผ์ด์ ์ด ์ค์ํ๋ค.
- A๋ผ๋ ๊ฐ๋ฐ์๊ฐ ๋ค์๊ณผ ๊ฐ์ ์ฝ๋๋ฅผ ๋ง๋ค์๋ค.
function makePerson(name, age) {}
- B๋ผ๋ ๊ฐ๋ฐ์๊ฐ ์ด ์ฝ๋๋ฅผ ์ด์ฉํ๋ ค๊ณ ๋ค์ ์ฝ๋๋ฅผ ๋ง๋ค์ด ์คํํ์ ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค๋ฉด, B ๊ฐ๋ฐ์๋ ์ค๋ฅ์ ์์ธ์ด ๋ฌด์์ธ์ง ์ฐพ๊ธฐ๊ฐ ์ด๋ ต๋ค.
makePerson(32, 'Jack');
- ๊ทธ๋ฐ๋ฐ ์ฒ์ ์ฝ๋๋ฅผ ๋ค์์ฒ๋ผ ํ์ ์คํฌ๋ฆฝํธ์ ํ์ ๊ฐ๋ฅ์ ์ด์ฉํด ๊ตฌํํ๋ค๋ฉด ์ด๋ฌํ ๋ฌธ์ ๋ ๋ฐ์ํ์ง ์์์ ๊ฒ์ด๋ค.
function makePerson(name: string, age: number) {}
- ๊ทธ๋ฆฌ๊ณ ํ์ ์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ๋ ๋ฌธ์ ์ ์์ธ์ด ์ด๋์ ์๋์ง ์น์ ํ๊ฒ ์๋ ค์ฃผ๋ฏ๋ก ์ฝ๋๋ฅผ ์ข ๋ ์์ํ๊ฒ ์์ฑํ ์ ์๋ค.
๐ ํธ๋์คํ์ผโ
- ESNext ์๋ฐ์คํฌ๋ฆฝํธ ์์ค์ฝ๋๋ ๋ฐ๋ฒจ(Babel)์ด๋ผ๋ ํธ๋์คํ์ผ๋ฌ๋ฅผ ๊ฑฐ์น๋ฉด ES5 ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ๋ณํ๋๋ค.
- ๋ฐ๋ฒจ๊ณผ ์ ์ฌํ๊ฒ ํ์ ์คํฌ๋ฆฝํธ ์์ค์ฝ๋๋ TSC(TypeScript complier)๋ผ๋ ํธ๋์คํ์ผ๋ฌ๋ฅผ ํตํด ES5 ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ๋ณํ๋๋ค.
- ํธ๋์คํ์ผ๋ฌ๋ ํ ์คํธ๋ก ๋ ์์ค์ฝ๋๋ฅผ ๋ฐ์ด๋๋ฆฌ ์ฝ๋๋ฅผ ๋ฐ๊ฟ์ฃผ๋ ์ปดํ์ผ๋ฌ์ ๊ตฌ๋ถํ๊ธฐ ์ํด ์๊ธด ์ฉ์ด์ด๋ค.
๐ฆ ํ์ ์คํฌ๋ฆฝํธ ์ฃผ์ ๋ฌธ๋ฒ ์ดํด๋ณด๊ธฐโ
- ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ๋ค๋ฃจ๋ ค๋ฉด ESNext ๋ฌธ๋ฒ์ ์์์ผ ํ๋ค.
- ํ์ ์คํฌ๋ฆฝํธ์๋ง ๊ณ ์ ํ ๋ฌธ๋ฒ๋ ์๋ค. ๋ ๊ฐ์ง ๋ฌธ๋ฒ์ ๊ตฌ๋ถํด์ ์์๋ณด์.
๐ ESNext์ ์ฃผ์ ๋ฌธ๋ฒ ์ดํด๋ณด๊ธฐโ
- ๋น๊ตฌ์กฐํ ํ ๋น
ESNext๋ ๋น๊ตฌ์กฐํ ํ ๋น(Destructuring Assignment)์ด๋ผ๊ณ ํ๋ ๊ตฌ๋ฌธ์ ์ ๊ณตํ๋ค.
๋น๊ตฌ์กฐํ ํ ๋น์ ๊ฐ์ฒด์ ๋ฐฐ์ด์ ์ ์ฉํ ์ ์๋ค.
// ๊ฐ์ฒด์ ์์ฑ์ ์ป๋ ์์
let person = { name: 'Jane', age: 22 };
let { name, age } = person; // name : Jane, age : 23
// ๋ฐฐ์ด์ ๋น๊ตฌ์กฐํ ํ ๋น์ ์ ์ฉํ ์์
let array = [1, 2, 3, 4];
let [head, ...rest] = array; // head = 1, rest = [2, 3, 4]
// ๊ฐ์ ์๋ก ๊ตํ(swap)ํ๋ ์
let a = 1, b = 2;
[a, b] = [b, a]; // a = 2, b = 1
- ํ์ดํ ํจ์
ESNext์์๋ function
ํค์๋ ์ธ์๋ ํ์ดํ๋ก ํจ์๋ฅผ ์ ์ธํ ์ ์๋ค.
// function ํค์๋ ์ฌ์ฉ
function add(a, b) {
return a + b;
}
// ํ์ดํ ํจ์ ์ฌ์ฉ
const add2 = (a, b) => a + b;
ํ์ดํ ํจ์๋ฅผ ์ฌ์ฉํ๋ฉด function
ํค์๋ ๋ฐฉ์๋ณด๋ค ์ฝ๋๋ฅผ ๊ฐ๊ฒฐํ๊ฒ ๋ง๋ค ์ ์๋ค.
- ํด๋์ค
ESNext์์๋ ํด๋์ค๋ผ๋ ๊ธฐ๋ฅ์ ์ ๊ณตํด C++๋ Java ์ธ์ด์์ ๋ณด๋ ๊ฐ์ฒด์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์ง์ํ๋ค.
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์ ์บก์ํ, ์์, ๋คํ์ฑ์ ์ง์ํ๋ค.
abstract class Animal {
constructor(public name?: string, public age?: number) {}
abstract say(): string
}
class Cat extends Animal {
say() {
return '์ผ์น';
}
}
class Dog extends Animal {
say() {
return '๋ฉ๋ฉ';
}
}
let animals: Animal[] = [new Cat('์ผ์น์ด', 2), new Dog('๋ฉ๋ฉ์ด', 3)];
let sounds = animals.map((a) => a.say()); // ['์ผ์น', '๋ฉ๋ฉ']
- ๋ชจ๋
๋ชจ๋์ ์ฌ์ฉํ๋ฉด ์ฝ๋๋ฅผ ์ฌ๋ฌ ๊ฐ ํ์ผ๋ก ๋ถํ ํด์ ์์ฑํ ์ ์๋ค.
๋ณ์๋ ํจ์, ํด๋์ค ๋ฑ์ export
ํค์๋๋ฅผ ์ฌ์ฉํด ๋ชจ๋๋ก ๋ง๋ค๋ฉด ๋ค๋ฅธ ํ์ผ์์๋ ์ฌ์ฉํ ์ ์๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ ๊ฒ ๋ง๋ ๋ชจ๋์ ๊ฐ์ ธ์ค๊ณ ์ถ์ ๋๋ import
ํค์๋๋ฅผ ์ฌ์ฉํ๋ค.
import * as fs from 'fs';
export function writeFile(filepath: string, content: any) {}
- ์์ฑ๊ธฐ
yield
๋ฌธ์ ๋ฐ๋ณต์๋ฅผ ์๋ฏธํ๋ ๋ฐ๋ณต๊ธฐ(iterator)๋ฅผ ์์ฑํ ๋ ์ฌ์ฉํ๋ค. ๊ทธ ๋ฐ๋ฐ ๋ฐ๋ณต๊ธฐ๋ ๋
๋ฆฝ์ ์ผ๋ก ์กด์ฌํ์ง ์๊ณ ๋ฐ๋ณต๊ธฐ ์ ๊ณต์(iterable)๋ฅผ ํตํด ์ป๋๋ค.
์ด์ฒ๋ผ yield
๋ฌธ์ ์ด์ฉํด ๋ฐ๋ณต๊ธฐ๋ฅผ ๋ง๋ค์ด ๋ด๋ ๋ฐ๋ณต๊ธฐ ์ ๊ณต์๋ฅผ ์์ฑ๊ธฐ(generator)๋ผ๊ณ ๋ถ๋ฅธ๋ค.
์์ฑ๊ธฐ๋ function
ํค์๋์ ๋ณํ(*
)๋ฅผ ๊ฒฐํฉํ function*
๊ณผ yield
ํค์๋๋ฅผ ์ด์ฉํด ๋ง๋ ๋ค.
ํ์
์คํฌ๋ฆฝํธ์์ yield
๋ ๋ฐ๋์ function*
์ผ๋ก ๋ง๋ค์ด์ง ํจ์ ๋ด๋ถ์์๋ง ์ฌ์ฉํ ์ ์๋ค.
function* gen() {
yield* [1, 2];
}
for(let value of gen()) {
console.log(value); // 1, 2
}
์์ ์ฝ๋์์ function*
์ ์์ฑ๊ธฐ๋ผ๊ณ ํ๋ค.
yield
๊ฐ ํธ์ถ๋๋ฉด ํ๋ก๊ทธ๋จ ์คํ์ด ์ผ์ ์ ์งํ ํ ์ ํํด์ for
๋ฌธ์ ์คํํ๋ค.
for
๋ฌธ์ ๋ง์น๋ฉด ๋ค์ yield
๋ก ๋์๊ฐ๊ณ ๋ฐฐ์ด์ ๋ชจ๋ ์์๋ฅผ ์ํํ ๋๊น์ง ๋ฐ๋ณตํ๋ค.
- Promise์ async/await ๊ตฌ๋ฌธ
ES5๋ก ๋น๋๊ธฐ ์ฝ๋ฐฑ ํจ์๋ฅผ ๊ตฌํํ๋ ค๋ฉด ์ฝ๋๊ฐ ์๋นํ ๋ณต์กํด์ง๊ณ ๋ฒ๊ฑฐ๋ก์์ง๋ค.
Promise
๋ ๋น๋๊ธฐ ์ฝ๋ฐฑ ํจ์๋ฅผ ์๋์ ์ผ๋ก ์ฝ๊ฒ ๊ตฌํํ ๋ชฉ์ ์ผ๋ก ๋ง๋ค์ด์ก๋ค.
ESNext์์๋ ์ฌ๋ฌ ๊ฐ์ Promise
ํธ์ถ์ ๊ฒฐํ ์ข ๋ ๋ณต์กํ ํํ์ ์ฝ๋๋ฅผ async/await
๊ตฌ๋ฌธ์ผ๋ก ๊ฐ๊ฒฐํ๊ฒ ๊ตฌํํ ์ ์๊ฒ ํ๋ค.
async function get() {
let values = [];
values.push(await Promise.resolve(1));
values.push(await Promise.resolve(2));
values.push(await Promise.resolve(3));
return values;
}
get().then(value => console.log(values)); // [1, 2, 3]
async
๋ฅผ ์ฌ์ฉํ ํจ์๋ ๋ณธ๋ฌธ์์ await
ํค์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
await
๋ Promise
๊ฐ์ฒด๋ฅผ ํด์(resolve)ํด ์ค๋ค. ๋ฐ๋ผ์ get
ํจ์๋ [1, 2, 3]
๊ฐ์ Promise
ํํ๋ก ๋ฐํํ๋ค.
get
์ด ๋ฐํํ Promise
๊ฐ์ฒด๋ then
๋ฉ์๋๋ฅผ ํธ์ถํด ์ค์ ๊ฐ์ ์ป์ ์ ์๋ค.
๐ ํ์ ์คํฌ๋ฆฝํธ ๊ณ ์ ์ ๋ฌธ๋ฒ ์ดํด๋ณด๊ธฐโ
- ํ์ ์ฃผ์๊ณผ ํ์ ์ถ๋ก
๋ค์ ์ฝ๋์์ ๋ณ์ n
๋ค์๋ ์ฝ๋ก (:
)๊ณผ ํ์
์ด๋ฆ์ด ์๋ค.
์ด๊ฒ์ด ํ์
์ฃผ์(type annotation)์ด๋ผ๊ณ ํ๋ค.
let n: number = 1;
๊ทธ๋ฐ๋ฐ ํ์
์คํฌ๋ฆฝํธ๋ ํ์
๋ถ๋ถ์ ์๋ตํ ์๋ ์๋ค.
ํ์
์คํฌ๋ฆฝํธ๋ ๋ณ์์ ํ์
๋ถ๋ถ์ด ์๋ต๋๋ฉด ๋์
์ฐ์ฐ์์ ์ค๋ฅธ์ชฝ ๊ฐ์ ๋ถ์ํด ์ผ์ชฝ ๋ณ์์ ํ์
์ ๊ฒฐ์ ํ๋ค.
์ด๋ฅผ ํ์
์ถ๋ก (type inference)์ด๋ผ๊ณ ํ๋ค.
let m = 2;
ํ์
์คํฌ๋ฆฝํธ์ ํ์
์ถ๋ก ๊ธฐ๋ฅ์ ์๋ฐ์คํฌ๋ฆฝํธ ์์ค ์ฝ๋์ ํธํ์ฑ์ ๋ณด์ฅํ๋ ๋ฐ ํฐ ์ญํ ์ ํ๋ค.
ํ์
์ถ๋ก ๋๋ถ์ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ์์ฑ๋ ํ์ผ(.js
)์ ํ์ฅ์๋ง .ts
๋ก ๋ณ๊ฒฝํ๋ฉด ํ์
์คํฌ๋ฆฝํธ ํ๊ฒฝ์์๋ ๋ฐ๋ก ๋์ํ๋ค.
- ์ธํฐํ์ด์ค
์๋์ Person
์ธํฐํ์ด์ค๋ string
ํ์
์ name
๊ณผ number
ํ์
์ age
๋ฅผ ๊ฐ๋๋ค.
?
๊ฐ ๋ถ์ ์์ฑ์ ๊ฐ์ฒด์ ์กด์ฌํ์ง ์์๋ person
๊ณผ ๊ฐ์ด ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์๋๋ค.
interface Person {
name: string;
age?: number;
}
let person: Person = { name: 'Jane' };
- ํํ
ํํ์ ๋ฌผ๋ฆฌ์ ์ผ๋ก๋ ๋ฐฐ์ด๊ณผ ๊ฐ๋ค.
๋ค๋ง, ๋ฐฐ์ด์ ์ ์ฅ๋๋ ์์ดํ
์ ๋ฐ์ดํฐ ํ์
์ด ๋ชจ๋ ๊ฐ์ผ๋ฉด ๋ฐฐ์ด, ๋ค๋ฅด๋ฉด ํํ์ด๋ค.
let numberArray: number[] = [1, 2, 3]; // ๋ฐฐ์ด
let tuple: [boolean, number, string] = [true, 1, 'Ok']; // ํํ
- ์ ๋ค๋ฆญ ํ์
์ ๋ค๋ฆญ ํ์
์ ๋ค์ํ ํ์
์ ํ๊บผ๋ฒ์ ์ทจ๊ธํ ์ ์๊ฒ ํด์ค๋ค.
๋ค์ ์ฝ๋์์ Container
ํด๋์ค๋ value
์์ฑ์ ํฌํจํ๋ค.
Container<number>
, Container<string>
, Container<number[]>
, Container<boolean>
์ฒ๋ผ ์ฌ๋ฌ ๊ฐ์ง ํ์
์ ๋์์ผ๋ก ๋์ํ ์ ์๋๋ฐ ์ด๋ฅผ ์ ๋ค๋ฆญ ํ์
์ด๋ผ๊ณ ํ๋ค.
class Container<T> {
constructor(public value: T) {};
}
let numberContainer: Container<number> = new Container<number>(1);
let stringContainer: Container<string> = new Container<string>('Hello World');
- ๋์ ํ์
ADT๋, ๋ฐ์ดํฐ ํ์
(abstract data type)์ ์๋ฏธํ๊ธฐ๋ ํ์ง๋ง ๋์ ํ์
(algebraic data type)์ด๋ผ๋ ์๋ฏธ๋ก๋ ์ฌ์ฉ๋๋ค.
๋์ ํ์
์ด๋, ๋ค๋ฅธ ์๋ฃํ์ ๊ฐ์ ๊ฐ์ง๋ ์๋ฃํ์ ์๋ฏธํ๋ค.
๋์ ํ์
์ ํฌ๊ฒ ํฉ์งํฉ ํ์
(union), ๊ต์งํฉ ํ์
(intersection) ๋ ๊ฐ์ง๊ฐ ์๋ค.
ํฉ์งํฉ ํ์
์ |
๊ธฐํธ๋ฅผ, ๊ต์งํฉ ํ์
์ &
๊ธฐํธ๋ฅผ ์ฌ์ฉํด ๋ค์ ์ฝ๋์ฒ๋ผ ์ฌ๋ฌ ํ์
์ ๊ฒฐํฉํด์ ๋ง๋ค ์ ์๋ค.
type NumberOrString = number | string;
type AnimalAndPerson = Animal & Person;
๐ฆ ํ์ ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ํ๊ฒฝ ๋ง๋ค๊ธฐโ
๐ scoop ํ๋ก๊ทธ๋จ ์ค์นโ
- ํ์ ์คํฌ๋ฆฝํธ ๊ฐ๋ฐ ํ๊ฒฝ์ Node.js ๊ฐ๋ฐ ํ๊ฒฝ๊ณผ ๋๊ฐ๋ค.
- ์ฆ, Node.js๋ฅผ ์ค์นํ๊ณ ๋น์ฃผ์ผ ์คํ๋์ค ์ฝ๋์ ํฌ๋กฌ๋ฅผ ์ค์นํ๋ฉด ๋ฐ๋ก ๊ฐ๋ฐํ ์ ์๋ค.
- scoop์ผ๋ก ์ค์นํ ํ๋ก๊ทธ๋จ๋ค์
scoop update *
๋ช ๋ น์ผ๋ก ํ๊บผ๋ฒ์ ๊ฐ์ฅ ์ต์ ๋ฒ์ ์ผ๋ก ์ ๋ฐ์ดํธ๋๋ค. (brew์ ๋น์ท..?) - scoop ๊ณต์ ์ฌ์ดํธ
๐ ๋น์ฃผ์ผ ์คํ๋์ค ์ฝ๋ ์ค์นโ
๐ Node.js ์ค์นโ
- Node.js ๋ค์ด๋ก๋
- macOS๋ brew๋ฅผ ์ฌ์ฉํ์ฌ ์ค์น๊ฐ๋ฅ
// ๋ฒ์ ํ์ธ
$ node --version
๐ ๊ตฌ๊ธ ํฌ๋กฌ ๋ธ๋ผ์ฐ์ ์ค์นโ
๐ ํ์ ์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ ์ค์นโ
- VSCode๋ฅผ ์คํํ๊ณ ํฐ๋ฏธ๋์ ๋ค์ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํด typescript ํจํค์ง๋ฅผ ์ค์นํ๋ค.
> npm i -g typescript
> tsc -v
- typescript ํจํค์ง๋ ์๋ฒ์ ํด๋ผ์ด์ธํธ๋ก ๋์ํ๋ ๋ ๊ฐ์ ํ๋ก๊ทธ๋จ์ ํฌํจํ๊ณ ์๋ค.
- ๋ฐ๋ผ์ ํ์
์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ ์ด๋ฆ์ ํจํค์ง ์ด๋ฆ๊ณผ ๋ฌ๋ฆฌ
tsc
์ด๋ค. ์ฆ, ํ์ ์คํฌ๋ฆฝํธ ์ปดํ์ผ๋ฌ์ ํด๋ผ์ด์ธํธ๋ผ๋ ์๋ฏธ๊ฐ ๋์์ ์๋ค.
๐ ํ์ ์คํฌ๋ฆฝํธ ์ปดํ์ผ๊ณผ ์คํโ
// hello.ts
console.log('Hello world!');
- ๋ค์์ฒ๋ผ ํฐ๋ฏธ๋์์ ๋ช
๋ น์ ์คํํ๋ฉด
hello.js
ํ์ผ์ด ์๊ธฐ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
> tsc hello.ts
- ์ฆ, ํ์ ์คํฌ๋ฆฝํธ ์์ค๊ฐ TSC์ ์ํด ํธ๋์คํ์ผ๋์ด hello.js ํ์ผ์ด ์์ฑ๋์๋ค.
- Node.js๋ก hello.js๋ฅผ ์คํํด๋ณธ๋ค.
> node hello.js
Hello world!
๐ ts-node ์ค์นโ
- tsc๋ ํ์ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ES5 ํ์์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋๋ก ๋ณํ๋ง ํ ๋ฟ ์คํํ์ง๋ ์๋๋ค.
- ํ์ ์คํฌ๋ฆฝํธ ์ฝ๋๋ฅผ ES5๋ก ๋ณํํ๊ณ ์คํ๊น์ง ๋์์ ํ๋ ค๋ฉด ts-node๋ผ๋ ํ๋ก๊ทธ๋จ์ ์ค์นํด์ผ ํ๋ค.
> npm i -g ts-node
- ์ค์น ํ,
--version
์ผ๋ก ํ๋ก๊ทธ๋จ ๋ฒ์ ์ ํ์ธํ๋ค.
> ts-node --version
- ์ด์ VSCode ํฐ๋ฏธ๋์์ ๋ค์ ๋ช ๋ น์ผ๋ก ์ปดํ์ผ๊ณผ ์คํ์ ๋์์ ์งํํด ๋ณธ๋ค.
> ts-node hello.ts
Hello world!