์คํฌ๋ํ
: ์ด๋ค ํน์ ํ ์น์ฌ์ดํธ์ ๊ฐ์ ๊ทธ ์ฌ์ดํธ์ HTML๋ฅผ ๊ธ์ด์ค๋ ๊ฒ์ด๋ค.
๐ก **์ธ์ ์ฐ์ด๋์?**์ฌ๋์ด๋ ์นดํก์ ์ฌ์ฉํ ๋, ๋งํฌ๋ฅผ ๊ณต์ ํ๋ฉด ๋ฐ์ ์๋์ผ๋ก ์ฌ์ดํธ์ ์๊ฐ์ ์ด๋ฏธ์ง๊ฐ ๋์ต๋๋ค!
ํ๋ก ํธ์๋๋ ๋ฐฑ์๋์์ ์ง์ ์ฌ์ดํธ์ ๊ฐ์ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฒ์
๋๋ค.
์ ์ ๊ฐ ๊ฒ์๊ธ์ ์์ฑํด์ ๋ฑ๋กํ ๋, ๋ฐฑ์๋ API๋ก ๊ธ์ ๋ด์ฉ์ ๋ณด๋ด์ฃผ๊ฒ ๋๋ค.
๊ธ์ ๋ด์ฉ์ http๊ฐ ํฌํจ๋ URL์ด ์๋ค๋ฉด, ๊ทธ ์ฌ์ดํธ์ ์ ์ํ์ฌ open graph
๊ฐ ์๋ ๋ด์ฉ์ ๊ธ์ด์์ ์ ์ฅํ๋ค.
ํฌ๋กค๋ง
: ์ฌ์ ์ ์๋ฏธ๋ก๋ ๊ธฐ์ด๋ค๋๋ค๋ ๋ป์ธ๋ฐ ์ฌ๋ฌ ์น ์ฌ์ดํธ๋ค์ ๋์๋ค๋๋ฉฐ ์คํฌ๋ํ(ํ์์ด)์ ์ ๊ธฐ์ ์ผ๋ก ์ฃผ๊ธฐ์ ์ผ๋ก ํ๋ ๊ฒ์ ๋งํ๋ค.
์คํฌ๋ํ์ ๋์์ฃผ๋ cheerio ์ค์นํ๊ธฐ
yarn add cheerio
======
//index.js
import axios from 'axios'
import cheerio from 'cheerio'
const createMessage = async () => {
// ์
๋ ฅ๋ ๋ฉ์์ง: "์๋
ํ์ธ์~ https://www.naver.com ์ ๋ฐฉ๋ฌธํด ์ฃผ์ธ์!"
// 1. ์
๋ ฅ๋ ๋ฉ์์ง์์ http๋ก ์์ํ๋ ๋ฌธ์ฅ์ด ์๋์ง ๋จผ์ ์ฐพ๊ธฐ!(.find() ๋ฑ์ ์๊ณ ๋ฆฌ์ฆ ์ฌ์ฉํ๊ธฐ)
const url = "https://www.daum.net"
// 2. axios.get์ผ๋ก ์์ฒญํด์ html์ฝ๋ ๋ฐ์์ค๊ธฐ => ์คํฌ๋ํ
const result = await axios.get(url)
console.log(result.data)
// 3. ์คํฌ๋ํ ๊ฒฐ๊ณผ(result)์์ OG(์คํ๊ทธ๋ํ) ์ฝ๋ ๊ณจ๋ผ๋ด์ ๋ณ์์ ์ ์ฅํ๊ธฐ
const $ = cheerio.load(result.data)
$("meta").each((i, el) => {
if($(el).attr("property") && $(el).attr("property").includes("og:")){
const key = $(el).attr("property") // og:title, og:description, ...
const value = $(el).attr("content") // ๋ค์ด๋ฒ, ๋ค์ด๋ฒ ๋ฉ์ธ์์ ~~~
console.log(key, value)
// attr: ์์ฑ์ ๊ฐ์ ธ์ค๋ ๋ฉ์๋
// each: Cherio ๊ฐ์ฒด๋ฅผ ๋ฐ๋ณตํ์ฌ ์ผ์นํ๋ ๊ฐ ์์์ ๋ํ ํจ์๋ฅผ ์คํ
}
})
}
createMessage()
class
: ํด๋์ค(class)
๋ ๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ์์ ํน์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ์ํด ๋ณ์์ ๋ฉ์๋๋ฅผ ์ ์ํ๋ ์ผ์ข
์ ํ๋ก ๊ฐ์ฒด๋ฅผ ์ ์ํ๊ธฐ ์ํ ์ํ(๋ณ์)์ ๋ฉ์๋(ํจ์) ๋ก ๊ตฌ์ฑ๋๋ค.
class โ ๋ฌผ๊ฑด ๋ง๋๋ ์ค๋ช ์
์ค๋ฌด์์ ์ฌ์ฉ์๋ ๋ฌผ๊ฑด๊ฐ์ด ๋์ผํ ์ข ๋ฅ์ ๊ฐ์ฒด๋ฅผ ์ฌ๋ฌ๊ฐ ์์ฑํด์ผ ํ๋ ๊ฒฝ์ฐ ํด๋์ค ์ฌ์ฉ
class Date{
getFullyear(){
}
getMonth(){
}
}
const aaa = new Date()
console.log(aaa.getFullyear())
console.log(aaa.getMonth() + 1)
=> aaa์ Date ๋ฅผ ํ ๋นํด์ฃผ๋ฉด getMonth,getFullyear ๊ฐ์ฒด ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
์ด๋ฌํ ๊ฐ์ฒด๋ฅผ **๋ด์ฅ๊ฐ์ฒด** ๋ผ๊ณ ํ๋ค.
class ๊ธฐ์ด
// index.js
class Monster {
power = 10
// ์์ฑ์ ๋ฐ์ new monster() ๊ฐ๋ก์ ์คํ์์ผ์ฃผ๋ ํจ์
constructor(qqq){ => ์ด๊ธฐ๊ฐ ์์ฑ๊ฐ๋ฅ!
this.power = qqq
}
attack = () => {
console.log("๊ณต๊ฒฉํ์!!!");
console.log("๋ด ๊ณต๊ฒฉ๋ ฅ์" + this.power + "์ผ");
}
run = () => {
console.log("๋๋ง์ณ!!!");
}
}
const mymonster1 = new Monster(20)
mymonster1.attack()
mymonster1.run()
const mymonster2 = new Monster(50)
mymonster2.attack()
mymonster2.run()
// ๊ฒฐ๊ณผ
๊ณต๊ฒฉํ์!!!
๋ด ๊ณต๊ฒฉ๋ ฅ์20์ผ
๋๋ง์ณ!!!
๊ณต๊ฒฉํ์!!!
๋ด ๊ณต๊ฒฉ๋ ฅ์50์ผ
๋๋ง์ณ!!!
class ์์ ์ค์ต(extends)
class Monster {
power = 10
// ์์ฑ์ ๋ฐ์ new monster() ๊ฐ๋ก์ ์คํ์์ผ์ฃผ๋ ํจ์
constructor(qqq){
this.power = qqq
}
attack = () => {
console.log("๊ณต๊ฒฉํ์!!!");
console.log("๋ด ๊ณต๊ฒฉ๋ ฅ์" + this.power + "์ผ");
}
run = () => {
console.log("๋๋ง์ณ!!!");
}
}
// ์์ํจํด์ ์จ์ค๋๋ extends์ ๋ถ์ฌ์ค๋ค!
class ๊ณต์ค๋ชฌ์คํฐ extends Monster{
// nest.js์์ ์ฌ์ฉํ๋ ๊ตฌ๋ฌธ
constructor(aaa){
super(aaa + 1)
}
// ์ค๋ฒ๋ผ์ด๋ฉ(๋ถ๋ชจ์ run์ ๋ฎ์ด์)
run = () => {
console.log("๋ ์์ ๋๋ง์ณ!!!");
}
}
class ์ง์๋ชฌ์คํฐ extends Monster{
// nest.js์์ ์ฌ์ฉํ๋ ๊ตฌ๋ฌธ
constructor(bbb){
super(bbb)
}
// ์ค๋ฒ๋ผ์ด๋ฉ(๋ถ๋ชจ์ run์ ๋ฎ์ด์)
run = () => {
console.log("๋ฐ์ด์ ๋๋ง์ณ!!!");
}
}
const mymonster1 = new ๊ณต์ค๋ชฌ์คํฐ(20)
mymonster1.attack()
mymonster1.run()
const mymonster2 = new ์ง์๋ชฌ์คํฐ(50)
mymonster2.attack()
mymonster2.run()
//๊ฒฐ๊ณผ
๊ณต๊ฒฉํ์!!!
๋ด ๊ณต๊ฒฉ๋ ฅ์21์ผ
๋ ์์ ๋๋ง์ณ!!!
๊ณต๊ฒฉํ์!!!
๋ด ๊ณต๊ฒฉ๋ ฅ์50์ผ
๋ฐ์ด์ ๋๋ง์ณ!!!
super
: ํ์ฌ power ๋ณ์๋ ์์ํด ์ค Monster ๋ด๋ถ์ ์กด์ฌํ๋ฏ๋ก, Monster class ๋ด๋ถ์ ์๋ constructor ๋ก ์ธ์๋ฅผ ๋๊ฒจ์ฃผ๊ธฐ ์ํด ์ฌ์ฉ
Class ์ ๋ต ํจํด ์ค์ต(****Strategy Pattern****)
class ๊ณต์ค๋ถํ {
run = () => {
console.log("๋ ๋ผ์ ๋๋ง์ณ!!!");
}
}
class ์ง์๋ถํ {
run = () => {
console.log("๋ฐ์ด์ ๋๋ง์ณ!!!");
}
}
class Monster {
power = 10
๋ถํ;
// ์์ฑ์ ๋ฐ์ new monster() ๊ฐ๋ก์ ์คํ์์ผ์ฃผ๋ ํจ์
constructor(qqq){
this.๋ถํ = qqq
}
attack = () => {
console.log("๊ณต๊ฒฉํ์!!!");
console.log("๋ด ๊ณต๊ฒฉ๋ ฅ์" + this.power + "์ผ");
}
run = () => {
this.๋ถํ.run()
}
}
const aaa = new ๊ณต์ค๋ถํ()
const bbb = new ์ง์๋ถํ()
const mymonster1 = new Monster(aaa)
mymonster1.attack()
mymonster1.run()
const mymonster2 = new Monster(bbb)
mymonster2.attack()
mymonster2.run()
๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ(Object-Oriented-Programming)?
โ ํ๋ก๊ทธ๋๋ฐ ํจ๋ฌ๋ค์
: ํ๋ก๊ทธ๋๋ฐ ์คํ์ผ, ์ ์ฒด์ ์ธ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์
์ํ์ ํ์๋ฅผ ๊ฐ์ง ๊ฐ์ฒด
๋ก ๋ง๋ค๊ณ , ๊ฐ์ฒด๋ค๊ฐ์ ์ํธ์์ฉ์ ํตํด ๋ก์ง์ ๊ตฌ์ฑํ๋ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ๋ฒ์ด๋ค.๊ฐ์ฒด ์งํฅ ํ๋ก๊ทธ๋๋ฐ(OOP)**์ 4๊ฐ์ง ํน์ง**
์์ฐ๋์ ๋ฒค์ธ ๋ ๋ชจ๋ ์๋์ฐจ์ ํด๋นํ๋ค.
๋ฐ๋ผ์ ์๋์ฐจ๋ผ๋ ์ง๋จ์ ์ถ์ํํ์ฌ ํ๋์ ์งํฉ์ผ๋ก ๋ง๋ค์ด ๋์ ์ ์๋ค.
์บก์ํ
: ํ๋์ ๊ฐ์ฒด์ ๋ํด ๊ทธ ๊ฐ์ฒด๊ฐ ํน์ ํ ๋ชฉ์ ์ ์ํ ํ์ํ ๋ณ์๋ ๋ฉ์๋๋ฅผ ํ๋๋ก ๋ฌถ๋ ๊ฒ
์์์ด๋ ๊ธฐ์กดย ์์ ํด๋์ค์ ๊ทผ๊ฑฐํ์ฌ ์๋กญ๊ฒ ํด๋์ค์ ํ์๋ฅผ ์ ์ํ ์ ์๊ฒ ๋์์ฃผ๋ ๊ฐ๋ ์ ๋๋ค.
๋คํ์ฑ์ ์์์ ํตํดย ๊ธฐ๋ฅ์ ํ์ฅํ๊ฑฐ๋ ๋ณ๊ฒฝํ๋ ๊ฒ์ ๊ฐ๋ฅํ๊ฒ ํด์ค๋๋ค. ์ฆ, ๋คํ์ฑ์ ํํ๊ฐ ๊ฐ์๋ฐ ๋ค๋ฅธ ๊ธฐ๋ฅ์ ํ๊ณ ์๋ก ๋ค๋ฅธ ํด๋์ค์ ๊ฐ์ฒด๊ฐ ๊ฐ์ ๋ฉ์์ง๋ฅผ ๋ฐ์์ ๋ ๊ฐ์์ ๋ฐฉ์์ผ๋ก ๋์ํ๋ ๋ฅ๋ ฅ์ ๋๋ค.
์ค๋ฒ๋ก๋ฉ(Overloading)
Design Pattern?
MVC(Model-View-Controller) Pattern
MVC ๋ ์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ์ธ๊ฐ๋ก ๊ตฌ์ฑ๋์ด ์๋ค. ํ๋์ ์ ํ๋ฆฌ์ผ์ด์ , ํ๋ก์ ํธ๋ฅผ ๊ตฌ์ฑํ ๋ ๊ทธ ๊ตฌ์ฑ์์๋ฅผ ์ธ๊ฐ์ง์ ์ญํ ๋ก ๊ตฌ๋ถํ ํจํด.
controllers
์์๋ ๋ฏธ๋ค์จ์ด ํจ์๋ฅผ ๋ถ๋ฆฌํด์ ๊ด๋ฆฌํด ์ค ๊ฒ์ด๋ค.
models
์์๋ DB ์์ฑ์ ๊ด๋ฆฌํด์ฃผ๋ ๊ณณ์ผ๋ก ์ด์ ์ ๋ฐฐ์ด Schema ์ ์๋ฅผ ํด ์ค ํด๋์ ๋์ผํ๋ค.
view
์๋ ํ๋ฉด์ ๋ณด์ฌ์ง๋ ํ์ผ๋ค(html ํ์ผ)์ ๊ด๋ฆฌํด์ฃผ๋ ํด๋
์์ ๊ทธ๋ฆผ์ฒ๋ผ ์ฌ์ฉ์๊ฐ controller๋ฅผ ์กฐ์ํ๋ฉด controller๋ model์ ํตํด์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ณ ๊ทธ ์ ๋ณด๋ฅผ ๋ฐํ์ผ๋ก ์๊ฐ์ ์ธ ํํ์ ๋ด๋นํ๋ View๋ฅผ ์ ์ดํด์ ์ฌ์ฉ์์๊ฒ ์ ๋ฌํ๊ฒ ๋๋ค.
Tight-coupling & Dependency
๊ฐํ ๊ฒฐํฉ(Tight Coupling)์ ํน์ง
์ค์ต
// coupon.controller.js
import { CashService } from "./services/cash.service.js";
export class CouponController {
buyCoupon = (req, res) => {
// 1. ๊ฐ์ง๋ ๊ฒ์ฆํ๋ ์ฝ๋ (10์ค => 2์ค)
const cashService = new CashService();
const hasMoney = cashService.checkValue(); // true ๋๋ false ๋ฆฌํด
// 2. ์ฟ ํฐ ๊ตฌ๋งคํ๋ ์ฝ๋
if (hasMoney) {
res.send("์ฟ ํฐ ๊ตฌ๋งค ์๋ฃ!!");
}
};
}
=> CouponController๊ฐ CashService์ ์์กดํ๊ณ ์์ผ๋ฏ๋ก Coupontrollerdhk CashService
๊ฐ ๊ฐํ๊ฒ ๊ฒฐํฉ๋์ด ์๋ค.
Loose-coupling & Dependency
๋์จํ๊ฒฐํฉ
: โ๊ฐ์ฒด๋ค ๊ฐ์ ๊ฒฐํฉ์ด ๋์ด์๊ธด ํ๋ฐ ํ๊ฒ๊ฒ ๋๋ค.โ๋ก ํด์ํ ์ ์๋ค.
๋ค๋ฅธ ํด๋์ค๋ฅผ ์ง์ ์ ์ผ๋ก ์ฌ์ฉํ๋ ํด๋์ค์ ์์กด์ฑ์ ์ค์ด์.
๋์จํ ๊ฒฐํฉ(Loose Coupling)์ ํน์ง
์ค์ต
const app = express();
// ์ถ๊ฐ๋๋ ๋ถ๋ถ
const cashService = new CashService();
// ์ํ API
const productController = new ProductController(cashService);
app.post("/products/buy", productController.buyProduct);
app.post("/products/refund", productController.refundProduct);
// ์ฟ ํฐ(์ํ๊ถ) API
const couponController = new CouponController();
app.post("/coupons/buy", couponController.buyCoupon);
app.listen(3000, () => {
console.log("๋ฐฑ์๋ API ์๋ฒ๊ฐ ์ผ์ก์ด์!!!");
});
cashServicer ๋ฅผ ๋ฐ์์ ์คํํด ์์ฑ์๋ก ๋ฃ์ด์ฃผ์๋ค. ์ฆ, ์ฑ๊ธํค ํจํด์ ์ ์ฉํ์ฌ
๋์จํ ๊ฒฐํฉ์ผ๋ก ๋ง๋ค์ด ์ฃผ์๋ค.
Singleton Pattern(์ฑ๊ธํค ํจํด)
// product.controller.js
import { ProductService } from './services/product.service.js'
// import { CashService } from "./services/point.service.js";
export class ProductController {
constructor(cashService) {
this.cashService = cashService;
}
buyProduct = (req, res) => {
// 1. ๊ฐ์ง๋ ๊ฒ์ฆํ๋ ์ฝ๋(10์ค => 2์ค => 1์ค)
// const cashService = new CashService();
const hasMoney = this.cashService.checkValue();
// ํ๋งค์ฌ๋ถ ๊ฒ์ฆํ๋ ์ฝ๋(10์ค => 2์ค)
const productService = new ProductService()
const isSoldout = productService.checkSoldout();
// 3. ์ํ ๊ตฌ๋งคํ๋ ์ฝ๋
if (hasMoney && !isSoldout) {
res.send("์ํ์ ๊ตฌ๋งคํฉ๋๋ค.");
}
};
refundProduct = (req, res) => {
// 1. ํ๋งค์ฌ๋ถ ๊ฒ์ฆํ๋ ์ฝ๋(10์ค => 2์ค => 1์ค)
const productService = new ProductService()
const isSoldout = productService.checkSoldout();
// 2. ์ํ ํ๋ถํ๋ ์ฝ๋
if (isSoldout) {
res.send("์ํ์ ํ๋ถํฉ๋๋ค.");
}
};
}
import express from 'express'
const app = express()
import { ProductController} from './mvc/controllers/product.controller.js'
import { CouponController } from './mvc/controllers/coupon.controller.js'
import { CashService } from './mvc/controllers/services/cash.service.js'
import { PointService } from './mvc/controllers/services/point.service.js'
import { ProductService } from './mvc/controllers/services/product.service.js'
// ์์กด์ฑ // == ์์กด์ฑ์ฃผ์
์ผ๋ก ๋ฐ์ํ๋ ์ฅ์ !! ==
const cashService = new CashService() // 1. new ํ๋ฒ์ผ๋ก ๋ชจ๋ ๊ณณ์์ ์ฌ์ฌ์ฉ ๊ฐ๋ฅ(์ฑ๊ธํคํจํด)
const productService = new ProductService()// 2. ์์กด์ฑ ์ฃผ์
์ผ๋ก ํ๊บผ๋ฒ์ ๋ณ๊ฒฝ ๊ฐ๋ฅ
const pointService = new PointService() // 3. ์์กด์ฑ ์ฃผ์
์ผ๋ก ์ฟ ํฐ ๊ตฌ๋งค ๋ฐฉ์์ ํฌ์ธํธ๊ฒฐ์ ๋ก ์์ ํ๊ฒ ๋ณ๊ฒฝ๊ฐ๋ฅ
// [๋ถ๊ฐ ์ค๋ช
]
// 1. ProductController๊ฐ CashService์ ์์กดํ๊ณ ์์.(CashService => ์์กด์ฑ)
// => ์ด ์ํฉ์ "๊ฐํ๊ฒ ๊ฒฐํฉ๋์ด ์๋ค" ๋ผ๊ณ ํํ
// => tight-coupling
// 2. ์ด๋ฅผ ๊ฐ์ ํ๊ธฐ ์ํด์ "๋์จํ ๊ฒฐํฉ"์ผ๋ก ๋ณ๊ฒฝํ ํ์๊ฐ ์์
// => loose-coupling
// => ์ด๋ฅผ "์์กด์ฑ ์ฃผ์
"์ผ๋ก ํด๊ฒฐ(์์กด์ฑ ์ฃผ์
:Dependency-Injection ===> DI:์ฝ์ )
// => ์ด ์ญํ ์ ๋์ ํด์ฃผ๋ Nest.js ๊ธฐ๋ฅ : IoC container (์ ์ด๋ฅผ ์ญ์ ์์ผ์ฃผ๋) => ์์์ new ํด์ ๋ฃ์ด์ฃผ๋์ . ์ฆ DI ํด์ค
// => Inversion-Of-Control
// 3. "์์กด์ฑ์ฃผ์
"์ผ๋ก "์ฑ๊ธํคํจํด" ๊ตฌํ ๊ฐ๋ฅํด์ง
// => โ"์์กด์ฑ ์ฃผ์
"์ด๋ฉด "์ฑ๊ธํค ํจํด" ์ธ๊ฐ..? ๊ทธ๊ฑด ์๋!!
// ์ํ API
const productController = new ProductController(cashService, productService)
app.post('/products/buy', productController.buyProduct) // ์ํ ๊ตฌ๋งคํ๊ธฐ API
app.post("/products/refund", productController.refundProduct) // ์ํ ํ๋ถํ๊ธฐ API
// ์ฟ ํฐ ์ํ๊ถ API
const couponController = new CouponController(cashService, pointService)
app.post("/coupons/buy", couponController.buyCoupon) // ์ํ๊ถ์ ๋์ฃผ๊ณ ๊ตฌ๋งคํ๋ API
// ๊ฒ์ํ API
// app.get("/boards/...")
app.listen(3000)
Type-script
function sumJs(a, b) {
return a + b;
}
function sumTs(a: number, b: number) {
return a + b;
}
sumJS(10, 20) // '1020'
sumTS(10, 20) // 30
์ด์ฒ๋ผ ํ์ ์ ์ง์ ํด์ฃผ์ง ์์ผ๋ฉด ์ซ์๊ฐ ์๋ ๋ฌธ์์ด๋ก ๋ํ๊ธฐ ๋๋ฌธ์ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ 1020์ด๋ผ๋ ๋ฌธ์์ด์ ๋ํ๋ด๊ฒ๋๋ค. ์ฌ์ ์ ํ์ ์๋ฌ๋ฅผ ๋ฐฉ์งํ ์ ์๋ค.
let aaa : string = "์๋
ํ์ธ์"
let bbb : number = 123
interface IProfile {
name : string;
age: number;
}
let profile:IProfile = { name: "์ฒ ์", age: 15 }
๊ฐ์ฒด์๋ interface
๋ฅผ ์ฌ์ฉํ์ฌ ํ์
์ ์ง์ ๋ง๋ค์ด์ ์ฌ์ฉํด์ผ ํ๋ค
๋ฐฐ์ด ํ์
์ง์
let fff : number[] = [1,2,3,4,5]
fff = ['์ฒ ์', '์ํฌ', 'ํ์ด' ] // ๋ฌธ์ ํ์
๋ถ๊ฐ
let ggg: string[] = ['์ฒ ์', '์ํฌ', 'ํ์ด']
let hhh: (number | string)[] = ['์ฒ ์', '์ํฌ', 'ํ์ด', 10]
// ํ์
์ ์ถ๋ก ํด์ ์ด๋ค ํ์
์ ์ฌ์ฉํ๋์ง ์์๋ณด๊ธฐ
๊ฐ์ฒด ํ์
์ง์
interface IProfile{
name: string
age: number | string
school: string
hobby? : string // ํ์์ ์ผ๋ก ์กด์ฌํ์ง ์์๋ ๋ ๋๋ ? ์ฌ์ฉํด์ ์ฐ๋๊ฑด ๋ด๋ง๋๋ก๋ผ๊ณ ์ง์
}
let profile: IProfile = {
name: "์ฒ ์",
age: 8,
school: "๋ค๋์ฅ์ด๋ฑํ๊ต"
}
profile.age = "8์ด" // ๐จ ๋ฌธ์ ํ์
๋ถ๊ฐ๋ฅ!
profile.hobby = "์์" // ๐จ ๊ธฐ์กด profile ๊ฐ์ฒด์๋ hobby๊ฐ ์๊ธฐ์ ๋ฐ์ดํฐ ์ถ๊ฐ ๋ถ๊ฐ๋ฅ!
ํจ์ ํ์
์ง์
// ํจ์ํ์
1
function add(num1: number, num1: number): number {
return num1 + num1
// return "์๋
ํ์ธ์!!" // ๐จ return ๊ฐ์ด ๋ฌธ์ ํ์
์ด๊ธฐ์ ๋ถ๊ฐ๋ฅ!
}
const result = add(1000, 2000)
// ํจ์ํ์
2
function add2(num1: number, num1: number, unit: string): string {
return num1 + num2 + unit
}
let result2 = add2(1000, 2000, "์") // result์ ํ์
์ string์ด ๋๋๊ฒ
ํจ์ ํ์ ์์๋ ๋งค๊ฐ๋ณ์ ๋ฐ๋ ์์น์์ ํ์ ์ ์ง์ ํด์ค์ผํ๋ค.
์คํ๋ ์ง์ ํด์ค ํ์ ๊ณผ ๋์ผํ๊ฒ ์์ฑํด์ ์คํ์์ผ์ค์ผํ๋ค.
Decorator ์๋ฆฌ ์ค์ต
โ ๋ฐ์ฝ๋ ์ดํฐ๋ ์คํํ๋ ค๋ ์ฌ์ฉ์๊ฐ ๊ตฌ์กฐ๋ฅผ ์์ ํ์ง ์๊ณ ๊ธฐ์กด ๊ฐ์ฒด์ ์๋ก์ด ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋๋ก ํ๋ ๋์์ธ ํจํด
โ ์ผ๋ฐ์ ์ผ๋ก ๋ฐ์ฝ๋ ์ดํฐํ๋ ค๋ ํจ์์ ์ ์์ ์ ํธ์ถ๋๋ค. ๋ฐ์ฝ๋ ์ดํฐ๋ ํจ์๋ฅผ ์ธ์๋ก ์ป๊ณ ๋๊ฐ๋ก ์๋ก์ด ํจ์๋ก ๋๋ ค์ฃผ๋ cllable(์ ๋ฌ๋ฐ์ object์ธ์๊ฐ ํธ์ถ ๊ฐ๋ฅํ์ง ํ๋จ)๊ตฌ์กฐ์ด๋ค.
โ ํด๋์ค,๋ฉ์๋,์ ๊ทผ์,ํ๋กํผํฐ,ํ๋ฆฌ๋ฏธํฐ์ ์ ์ฉ๋ ์ ์๋ฐ.
index.ts
ํ์ผ์ ์คํ์์ผ์ฃผ๊ธฐ ์ ์ decorator
๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ TypeScript ํ์ผ ์ค์ ์ ๋จผ์ ํด์ฃผ๊ฒ ์ต๋๋ค.
07-02-typescript-decorator
ํด๋๋ก ํฐ๋ฏธ๋์ ์ด๋ํ์ฌ ์๋ ์์๋๋ก ์งํํด ์ฃผ์๋ฉด ๋ฉ๋๋ค.
**yarn init**
๋ช
๋ น์ด๋ฅผ ์
๋ ฅํด์ฃผ๊ณ , ๋ชจ๋ ์ง๋ฌธ์ ์ํฐ๋ฅผ ๋๋ฌ ๋์ด๊ฐ๋๋ค.
์ด๋ฅผ ํตํด package.json
ํ์ผ์ด ์์ฑ๋ฉ๋๋ค.
{
"name": "07-02-typescript-decorator",
"version": "1.0.0",
"main": "index.js",
"license": "MIT"
}
yarn add typescript --dev
๋ฅผ ์
๋ ฅํด ํ์
์คํฌ๋ฆฝํธ ๋ชจ๋์ ์ค์นํด์ฃผ์ธ์.{
"name": "07-02-typescript-decorator",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"typescript": "^4.8.4"
}
}
**yarn add ts-node**
๋ฅผ ์
๋ ฅํด ts-node๋ฅผ ์ค์นํด ์ฃผ์ธ์.{
"name": "07-02-typescript-decorator",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"devDependencies": {
"typescript": "^4.8.4"
},
"dependencies": {
"ts-node": "^10.9.1"
}
}
ts-node๋ฅผ ์ค์นํ๊ฒ ๋๋ฉด ํ์ ์คํฌ๋ฆฝํธ ํ์ผ์ ์คํํด ๋ณผ ์ ์์ต๋๋ค.
ํ์ ์คํฌ๋ฆฝํธ ์์ฒด๋ก๋ ์คํ์ด ๋ถ๊ฐ๋ฅํ๊ธฐ์ ํ์ ์คํฌ๋ฆฝํธ๋ฅผ ์๋ฐ์คํฌ๋ฆฝํธ๋ก ๋ณํํ์ฌ ์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ ๊ฒ์ ๋๋ค.
์คํ์ํค๋ ๋ช ๋ น์ด๋ฅผ ์ถ๊ฐํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
์๋์ ๊ฐ์ด scripts
๋ฅผ ์ถ๊ฐํด์ฃผ์ธ์.
{
"name": "07-02-typescript-decorator",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"scripts": {
"start:dev": "ts-node index.ts"
},
"devDependencies": {
"typescript": "^4.8.4"
},
"dependencies": {
"ts-node": "^10.9.1"
}
}
**yarn tsc --init
** ๋ฅผ ์
๋ ฅํด tsconfig.json
์์ฑํด์ฃผ์ธ์.// tsconfig.json
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"experimentalDecorators": true,
"noImplicitAny": false
}
}
"experimentalDecorators": true
๋ฅผ ์ถ๊ฐํด ์ฃผ์ธ์."noImplicitAny": false
๋ฅผ ์ถ๊ฐํด ์ฃผ์ธ์.$ yarn start:dev
๋ฅผ ์
๋ ฅํด์ index.ts
ํ์ผ์ ์คํ์์ผ์ฃผ์ธ์.
ProductController
ํด๋์ค ์์ ๋ฐ์ฝ๋ ์ดํฐ Controller
๋ฅผ ์์ฑํ์ต๋๋ค. ProductController
ํด๋์ค๊ฐ ํจ์์ ๋งค๊ฐ๋ณ์๋ก ๋ฐ์์ ธ์ ํจ์ Controller
๋ด๋ถ์์ ์ฌ์ฉ๋จ์ผ๋ก, Controller
๋ฐ์ฝ๋ ์ดํฐ๊ฐ ์ฌ์ค์ ํจ์์๋ค๋ ๊ฒ์ ์ ์ ์์ต๋๋ค.