ํจ์ ํ์
ํจ์ ํ์ ์ ์ ์ํ๋ค๋ ๊ฒ์ ์ด๋ค ํ์ ์ ๋งค๊ฐ๋ณ์๋ฅผ ๋ฐ๊ณ , ์ด๋ค ํ์ ์ ๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํ๋ ์ง๋ฅผ ์ ์ํ๋ ๊ฒ์ด๋ค. ํ์ ์คํฌ๋ฆฝํธ์์ ์ผ๋ฐ์ ์ธ ํจ์ ์ ์ธ๋ฌธ์ ํ์ ์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ๋ค.
function func(a: number, b: number): number {
return a + b;
}
ํ์ ์คํฌ๋ฆฝํธ๋ ๋ฐํ๋ฌธ์ ๊ธฐ์ค์ผ๋ก ๋ฐํ๊ฐ์ ํ์ ์ ์๋ ์ถ๋ก ํ ์ ์๊ธฐ ๋๋ฌธ์ ๋ฐํ๊ฐ ํ์ ์ ์๋ตํ ์ ์๋ค.
function func(a: number, b: number) {
return a + b;
}
ํ์ดํ ํจ์ ํ์ ์ ์
ํ์ดํ ํจ์์ ํ์ ์ ์ ์ํ๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ๋ค. ๋ง์ฐฌ๊ฐ์ง๋ก ๋ฐํ๊ฐ์ ํ์ ์ ์๋์ผ๋ก ์ถ๋ก ๊ฐ๋ฅํ๋ค.
const func = (a: number, b: number): number => a + b;
ํจ์์ ๋งค๊ฐ๋ณ์
๋งค๊ฐ๋ณ์ ๊ธฐ๋ณธ๊ฐ
ํจ์์ ๋งค๊ฐ๋ณ์์๋ ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํ ์ ์๋ค. ์ด ๊ฒฝ์ฐ ํด๋น ๋งค๊ฐ๋ณ์๋ ํ์ ์ ์ ์ํ์ง ์์๋ ์๋์ผ๋ก ์ถ๋ก ๋๋ค.
function introduce(name="์๊ฒฝ") {
console.log(`name: ${name});`
}
introduce(); // ์๊ฒฝ
์ ํ์ ๋งค๊ฐ๋ณ์
๋งค๊ฐ๋ณ์ ์ด๋ฆ ๋ค์ ?
๋ฅผ ๋ถ์ด๋ฉด ์๋ตํ ์ ์๋ ์ ํ์ ๋งค๊ฐ๋ณ์๋ก ๋ง๋ค์ด ์ค ์ ์๋ค.
function introduce(name="์๊ฒฝ", tall?: number) {
console.log(`name: ${name}`);
console.log(`tall: ${tall}`);
}
์ ์์ ์ ๊ฒฝ์ฐ ๋งค๊ฐ๋ณ์ tall
์ ์๋์ผ๋ก number ํ์
๊ณผ undefined ํ์
์ ์ ๋์จ ํ์
์ผ๋ก ์ถ๋ก ๋๋ค. ๋ฐ๋ผ์ ํจ์ ๋ด๋ถ์์ number ํ์
์ผ๋ก์ ์ฐ์ฐ ํน์ ๋ฉ์๋๋ฅผ ํธ์ถํ๊ณ ์ถ๋ค๋ฉด ํ์
์ขํ๊ธฐ๊ฐ ํ์ํ๋ค.
function introduce(name = "์๊ฒฝ", tall?: number) {
console.log(`name: ${name}`);
if (typeof tall === "number") {
console.log(`tall: ${tall + 10}`);
}
}
์ด๋ ์ฃผ์ํ ์ ์ ์ ํ์ ๋งค๊ฐ๋ณ์๊ฐ ํ์ ๋งค๊ฐ๋ณ์๋ณด๋ค ์์ ์ฌ ์ ์๋ค๋ ๊ฒ์ด๋ค.
function introduce(name="์๊ฒฝ", tall?: number, age: number) { // โ ์ค๋ฅ ๋ฐ์
(...)
}
๋๋จธ์ง ๋งค๊ฐ๋ณ์
๋๋จธ์ง ๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ ๋ช๊ฐ์ ์ซ์ ํ์ ์ ๊ฐ์ด ๋ค์ด์ค๋ ์ง ๊ฐ์ ๊ทธ ๊ฐ๋ค์ ํฉ์ ๊ตฌํ๋ ํจ์๋ฅผ ๋ง๋ ๋ค๊ณ ๊ฐ์ ํด๋ณด์. ์ด๋ ๋๋จธ์ง ๋งค๊ฐ๋ณ์์๋ number ํ์ ์ ์ธ์๋ค์ ๋ด์ ๋ฐฐ์ด์ด ๋ค์ด์ค๋ฏ๋ก ์๋์ ๊ฐ์ด ํ์ ์ ์ ์ํ ์ ์๋ค.
function getSum(...rest: number[]) {
let sum = 0;
rest.forEach((it) => (sum += it));
return sum;
}
getSum(1, 2, 3); // 6
getSum(1, 2, 3, 4, 5); // 15
๋ง์ฝ ๋๋จธ์ง ๋งค๊ฐ ๋ณ์์ ๊ธธ์ด๋ฅผ ๊ณ ์ ํ๊ณ ์ถ๋ค๋ฉด ํํ ํ์ ์ ์ฌ์ฉํ ์ ์๋ค.
function getSumOfThree(...rest: [number, number, number]) {
let sum = 0;
rest.forEach((it) => (sum += it));
return sum;
}
getSumOfThree(1, 2, 3); // 6
getSumOfThree(1, 2, 3, 4, 5); // โ
ํจ์ ํ์ ํํ์
ํจ์ ํ์ ํํ์(Function Type Expression)์ด๋ ํจ์ ํ์ ์ ํ์ ๋ณ์นญ๊ณผ ํจ๊ป ๋ณ๋๋ก ์ ์ํ ๊ฒ์ด๋ค. ํจ์ ํ์ ํํ์์ ์ด์ฉํ๋ฉด ํจ์ ํ์ ์ ์ธ๊ณผ, ํจ์์ ์ ์ธ ๋ฐ ์ฝ๋ ๊ตฌํ์ ๋ถ๋ฆฌํ ์ ์๋ค.
type Add = (a: number, b: number) => number; // ํจ์ ํ์
ํํ์
const add: Add = (a, b) => a + b;
๋ํ ํจ์ ํ์ ํํ์์ ์ฌ์ฉํ๋ฉด ์๋์ ๊ฐ์ด ์ฌ๋ฌ ๊ฐ์ ํจ์๊ฐ ๋์ผํ ํ์ ์ ๊ฐ์ง ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ ์ ์๋ค.
type Operation = (a: number, b: number) => number;
const add: Operation = (a, b) => a + b;
const sub: Operation = (a, b) => a - b;
const multiply: Operation = (a, b) => a * b;
const divide: Operation = (a, b) => a / b;
ํธ์ถ ์๊ทธ๋์ฒ
ํธ์ถ ์๊ทธ๋์ฒ(Call Signature)๋ ํจ์ ํ์ ํํ์๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ํจ์ ํ์ ์ ๋ณ๋๋ก ์ ์ํ๋ ๋ฐฉ์ ์ค ํ๋๋ค. ํธ์ถ ์๊ทธ๋์ฒ๋ ํจ์์ ํ์ ์ ๋ง์น ๊ฐ์ฒด์ ํ์ ์ ์ ์ํ ๋ฏ ์ ์ํ๋ค. ์ด๋ ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ํจ์๋ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ์ ๊ฐ๋ฅํ๋ค.
type Operation2 = {
(a: number, b: number): number;
};
const add2: Operation2 = (a, b) => a + b;
const sub2: Operation2 = (a, b) => a - b;
const multiply2: Operation2 = (a, b) => a * b;
const divide2: Operation2 = (a, b) => a / b;
ํ์ด๋ธ๋ฆฌ๋ ํ์
ํธ์ถ ์๊ทธ๋์ฒ ์๋์ ํ๋กํผํฐ๋ฅผ ์ถ๊ฐ ์ ์ํ๋ฉด, ํด๋น ํ์ ์ ์ฌ์ฉํ๋ ๋ณ์๋ ํจ์๋ก๋ ์ฌ์ฉํ ์ ์๊ณ , ์ผ๋ฐ ๊ฐ์ฒด๋ก๋ ์ฌ์ฉํ ์ ์๋ค.
type Type = {
(a: number): void;
name: string;
};
const func: Type = (a) => {
console.log(a);
};
func(1);
func.name = "func";
ํจ์ ํ์ ์ ํธํ์ฑ
ํจ์ ํ์ ์ ํธํ์ฑ์ ๊ธฐ๋ณธ ํ์ , ๊ฐ์ฒด ํ์ ํธํ์ฑ๊ณผ ๋ง์ฐฌ๊ฐ์ง๋ก ํน์ ํจ์ ํ์ ์ ๋ค๋ฅธ ํจ์ ํ์ ์ผ๋ก ์ทจ๊ธํด๋ ๊ด์ฐฎ์์ง๋ฅผ ํ๋จํ๋ ๊ฒ์ด๋ค. ํจ์ ํ์ ์ ํธํ์ฑ์ ๋ ๊ฐ์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋จํ ์ ์๋ค.
- ๋ฐํ๊ฐ์ ํ์ ์ด ํธํ๋๋๊ฐ
- ๋งค๊ฐ๋ณ์์ ํ์ ์ด ํธํ๋๋๊ฐ
๊ธฐ์ค1. ๋ฐํ๊ฐ ํ์ ์ด ํธํ๋๋๊ฐ
type A = () => number;
type B = () => 10;
let a: A = () => 10; // number ํ์
๋ฐํ
let b: B = () => 10; // 10 Number Literal ํ์
๋ฐํ
a = b; // โ
b = a; // โ
์์ ์์ ์์ ํจ์ a
์ ๋ฐํ๊ฐ ํ์
์ number ํ์
์ด๊ณ , ํจ์ b
์ ๋ฐํ๊ฐ ํ์
์ 10 Number Literal ํ์
์ด๋ค. ์ด ๊ฒฝ์ฐ, a
์ b
๋ฅผ ํ ๋นํ๋ ๊ฒ์ ๊ฐ๋ฅํ์ง๋ง, b
์ a
๋ฅผ ํ ๋นํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ค. ์ฆ, ํ ๋น๋๋ ํจ์ ํ์
์ ๋ฐํ๊ฐ์ด ํ ๋นํ๋ ค๋ ํจ์ ํ์
์ ๋ฐํ๊ฐ์ ์ํผ ํ์
์ธ ๊ฒฝ์ฐ ๋ ํจ์ ํ์
์ ํธํ๋๋ค.
๊ธฐ์ค2. ๋งค๊ฐ๋ณ์ ํ์ ์ด ํธํ๋๋๊ฐ
๋งค๊ฐ๋ณ์์ ํ์ ์ด ํธํ๋๋์ง ์ฌ๋ถ๋ '๋งค๊ฐ๋ณ์์ ๊ฐ์๊ฐ ๊ฐ์ ๋'์ '๋งค๊ฐ๋ณ์์ ๊ฐ์๊ฐ ๋ค๋ฅผ ๋'๋ก ๋๋ ์ ์๋ค.
๋งค๊ฐ๋ณ์์ ๊ฐ์๊ฐ ๊ฐ์ ๋
type C = (value: number) => void;
type D = (value: 10) => void;
let c: C = (value) => {};
let d: D = (value) => {};
c = d; // โ ์
์บ์คํ
์ผ ๋ ๋ถ๊ฐ
d = c; // โ
๋ค์ด์บ์คํ
์ผ ๋ ๊ฐ๋ฅ
์ ์์ ์์ C ํ์
์ ๋งค๊ฐ๋ณ์ ํ์
์ด D ํ์
์ ๋งค๊ฐ๋ณ์ ํ์
๋ณด๋ค ๋๋ค(C ํ์
์ ๋งค๊ฐ๋ณ์ ํ์
์ด D ํ์
์ ๋งค๊ฐ๋ณ์ ํ์
์ ์ํผ ํ์
์ด๋ค.). ์ด ๊ฒฝ์ฐ์ C ํ์
์ธ ํจ์ c
์ D ํ์
์ธ ํจ์ d
๋ฅผ ํ ๋นํ๋ ๊ฒ์ด ๋ถ๊ฐ๋ฅํ๋ฉฐ, ๊ทธ ๋ฐ๋๋ ๊ฐ๋ฅํ๋ค. ์ฆ, ๋ฐํ๊ฐ๊ณผ๋ ๋ค๋ฅด๊ฒ ๋งค๊ฐ๋ณ์์ ๊ฐ์๊ฐ ๊ฐ์ ๊ฒฝ์ฐ์ ํ ๋น๋๋ ํจ์ ํ์
์ ๋งค๊ฐ๋ณ์ ํ์
์ด ํ ๋นํ๋ ค๋ ํจ์ ํ์
์ ๋งค๊ฐ๋ณ์ ํ์
์ ์๋ธ ํ์
์ธ ๊ฒฝ์ฐ ๋ ํจ์ ํ์
์ ํธํ๋๋ค.
๊ฐ์ฒด์ ๊ฒฝ์ฐ๋ฅผ ์ดํด๋ณด๋ฉด ์ ๊ทธ๋ฐ์ง ์ข ๋ ๋ช ํํ๊ฒ ์ดํด๊ฐ ๊ฐ๋ฅํ๋ค.
type Animal = {
name: string;
};
type Dog = {
name: string;
color: string;
};
let animalFunc = (animal: Animal) => {
console.log(animal.name);
};
let dogFunc = (dog: Dog) => {
console.log(dog.name);
console.log(dog.color);
};
์ ์์ ์์ Animal ํ์
์ Dog ํ์
์ ์ํผ ํ์
์ด๋ค. ๊ฐ ํ์
์ ์ฌ์ฉํ๋ animalFunc
์ dogFunc
๋ฅผ ํ ๋นํ๋ ค๊ณ ํ ๋๋ฅผ ์๊ฐํด๋ณด์.
animalFunc = dogFunc; // โ
let testFunc = (animal: Animal) => {
console.log(animal.name);
console.log(animal.color); // ?
};
ํ์
์ด ๋ ๋์ animalFunc
๋ณ์์ dogFunc
๋ฅผ ํ ๋นํ๋ ๊ฒ์ ์ฝ๋๋ก ๋ํ๋ด๋ณด๋ฉด testFunc
์ ๊ฐ์ด ํํํ ์ ์๋ค. ํ์ง๋ง ์ด ๊ฒฝ์ฐ, Animal ํ์
์๋ ์๋ color
ํ๋กํผํฐ์ ์ ๊ทผํ๋ ค๊ณ ํ๊ธฐ ๋๋ฌธ์ ๋น์ฐํ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค. ๋ฐ๋ผ์, ๋ ๋์ ํ์
์ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ํจ์์ ์ข์ ํ์
์ ๋งค๊ฐ๋ณ์๋ฅผ ๊ฐ์ง ํจ์๋ฅผ ๋์
ํ ์ ์๋ค.
๋งค๊ฐ๋ณ์์ ๊ฐ์๊ฐ ๋ค๋ฅผ ๋
๋งค๊ฐ๋ณ์์ ๊ฐ์๊ฐ ๋ค๋ฅผ ๋๋ ๋งค๊ฐ ๋ณ์๊ฐ ๋ ๋ง์ ์ชฝ์ ๋งค๊ฐ ๋ณ์๊ฐ ๋ ์ ์ ์ชฝ์ ํ ๋นํ ์ ์์ผ๋ฉฐ, ๊ทธ ๋ฐ๋๋ ๋ถ๊ฐ๋ฅํ๋ค.
type Func1 = (a: number, b: number) => void;
type Func2 = (a: number) => void;
let func1: Func1 = (a, b) => {};
let func2: Func2 = (a) => {};
func1 = func2; // โ
func2 = func1; // โ
ํจ์ ์ค๋ฒ๋ก๋ฉ
ํจ์ ์ค๋ฒ๋ก๋ฉ์ด๋ ํจ์๋ฅผ ๋งค๊ฐ๋ณ์์ ๊ฐ์๋ ํ์ ์ ๋ฐ๋ผ ์ฌ๋ฌ๊ฐ์ง ๋ฒ์ ์ผ๋ก ์ ์ํ๋ ๊ฒ์ ์๋ฏธํ๋ค. ์๋ฐ์คํฌ๋ฆฝํธ์์๋ ํจ์ ์ค๋ฒ๋ก๋ฉ์ ์ง์ํ์ง ์์ผ๋ฉฐ, ํ์ ์คํฌ๋ฆฝํธ์์๋ ์ฌ์ฉํ ์ ์๋ค.
ํจ์ ์ค๋ฒ๋ก๋ฉ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๊ฐ์ฅ ๋จผ์ ํ๋์ ํจ์๊ฐ ๊ฐ์ง ์ ์๋ ์ข ๋ฅ๋ฅผ ์ ์ํ๋ ์ค๋ฒ๋ก๋ ์๊ทธ๋์ฒ ์ ์๊ฐ ํ์ํ๋ค. ๊ทธ๋ฆฌ๊ณ ํด๋น ํจ์๊ฐ ์ด๋ป๊ฒ ์คํ๋ ๊ฒ์ธ์ง๋ฅผ ์ ์ํ๋ ๊ตฌํ ์๊ทธ๋์ฒ๋ฅผ ์ ์ํด์ผ ํ๋ค.
// ๋ฒ์ ๋ค → ์ค๋ฒ๋ก๋ ์๊ทธ๋์ฒ
function func(a: number): void; // ๋ฒ์ 1
function func(a: number, b: number, c: number): void; // ๋ฒ์ 2
// ์ค์ ๊ตฌํ๋ถ → ๊ตฌํ ์๊ทธ๋์ฒ
function func() {}
func(); // โ
func(1); // โ
๋ฒ์ 1
func(1, 2); // โ
func(1, 2, 3); // โ
๋ฒ์ 2
์ ์์ ์์ ๊ตฌํ ์๊ทธ๋์ฒ์ ํจ์ ๋งค๊ฐ๋ณ์์ ์๋ฌด๊ฒ๋ ์๊ธฐ ๋๋ฌธ์ func()
๋ง์ด ์ค๋ฅ์์ด ๋์ํ ๊ฒ ๊ฐ์ง๋ง, ๊ทธ๋ ์ง ์๊ณ ์ค๋ฒ๋ก๋ ์๊ทธ๋์ฒ์์ ์ ์ํ ๊ฒ๊ณผ ์ผ์นํ๋ ํธ์ถ๋ง ์ ์์ ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
๊ตฌํ ์๊ทธ๋์ฒ๋ฅผ ์ ์ํ ๋ ๋งค๊ฐ๋ณ์ ํ์
์ ๋ชจ๋ ์๊ทธ๋์ฒ์ ํธํ๋๋๋ก ๋ง๋ค์ด์ผ ํ๋ค. ๋ฐ๋ผ์ ์ ์์ ์ ๊ฒฝ์ฐ b
์ c
๋ฅผ ์ ํ์ ๋งค๊ฐ๋ณ์๋ก ๋ง๋ค์ด์ ์ฒซ๋ฒ์งธ ์ค๋ฒ๋ก๋ ์๊ทธ๋์ฒ์ ํธํ๋ ์ ์๋๋ก ๋ง๋ค์ด์ฃผ์ด์ผ ํ๋ค.
function func(a: number, b?: number, c?: number) {
if (typeof b === "number" && typeof c === "number") {
console.log(a + b + c);
} else {
console.log(a * 20);
}
}
func(1);
func(1, 2, 3);
์ฌ์ฉ์ ์ ์ ํ์ ๊ฐ๋
์ฌ์ฉ์ ์ ์ ํ์ ๊ฐ๋๋ ์ฐธ ๋๋ ๊ฑฐ์ง์ ๋ฐํํ๋ ํจ์๋ฅผ ์ด์ฉํด ์ฌ์ฉ์ ์ ์๋๋ก ํ์ ๊ฐ๋๋ฅผ ๋ง๋ค ์ ์๋ ๋ฌธ๋ฒ์ด๋ค.
type Dog = {
name: string;
isBark: boolean;
};
type Cat = {
name: string;
isScratch: boolean;
};
type Animal = Dog | Cat;
function warning(animal: Animal) {
if ("isBark" in animal) {
animal;
} else if ("isSractch" in animal) {
animal;
}
}
์ ์์ ์์ warning
ํจ์ ์์์ ํ์
๊ฐ๋๋ฅผ ์ฌ์ฉํ์ฌ animal
์ Dog ํ์
ํน์ Cat ํ์
์ผ๋ก ์ขํ๋ ค๊ณ ํ๊ณ ์๋ค. ํ์ง๋ง ์ด๋ ๊ฐ๋
์ฑ๋ ๋จ์ด์ง๊ณ , ๋ง์ฝ ํ๋กํผํฐ ์ด๋ฆ์ด ๋ฐ๋๋ฉด ํ์
๊ฐ๋์ ์ฝ๋๋ ๋ณ๊ฒฝํด์ฃผ์ด์ผ ํ๋ค๋ ๋ฌธ์ ๊ฐ ์๋ค. ์ด๋ด ๋ ์ฌ์ฉ์ ์ ์ ํ์
๊ฐ๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
function isDog(animal: Animal): animal is Dog {
return (animal as Dog).isBark !== undefined;
}
function isCat(animal: Animal): animal is Cat {
return (animal as Cat).isScratch !== undefined;
}
function warning(animal: Animal) {
if (isDog(animal)) {
animal;
} else if (isCat(animal)) {
animal;
}
}
์ด์ฒ๋ผ ์ฌ์ฉ์ ์ ์ ํ์
๊ฐ๋๋ฅผ ์ ์ํ๋ ํจ์์์ ๋ฐํ๊ฐ์ ํ์
์ ๋งค๊ฐ๋ณ์๋ช
is ํ์
์ผ๋ก ์ ์ํ๋ฉด ํด๋น ํจ์๊ฐ true๋ฅผ ๋ฐํํ๋ฉด ๋งค๊ฐ๋ณ์๊ฐ ํด๋น ํ์
์์ ๋ณด์ฅํ๋ค๋ ์๋ฏธ๊ฐ ๋๋ค. ๋ฐ๋ผ์ ์ ์์ ์์ warning
ํจ์์ ์ฒซ ๋ฒ์งธ ์กฐ๊ฑด๋ฌธ ๋ด๋ถ์์๋ animal
์ด Dog ํ์
์ผ๋ก ์ขํ์ง๊ณ , ๋ ๋ฒ์งธ ์กฐ๊ฑด๋ฌธ ๋ด๋ถ์์๋ Cat ํ์
์ผ๋ก ์ขํ์ง๋ค.
์ฐธ๊ณ
๋ณธ ํฌ์คํธ๋ ์ด์ ํ๋์ 'ํ ์ ํฌ๊ธฐ๋ก ์๋ผ๋จน๋ ํ์ ์คํฌ๋ฆฝํธ(TypeScript)' ๊ฐ์๋ฅผ ์๊ฐํ๋ฉฐ ์์ฑํ์์ต๋๋ค.
ํ ์ ํฌ๊ธฐ๋ก ์๋ผ๋จน๋ ํ์ ์คํฌ๋ฆฝํธ(TypeScript) ๊ฐ์ | ์ด์ ํ Winterlood - ์ธํ๋ฐ
์ด์ ํ Winterlood | , ํ๋ก ํธ์๋์ ํผํ ์ ์๋ ๋์ธ ํ์ ์คํฌ๋ฆฝํธ,์ด์ ๋ ์ ๋๋ก ์ ๋ณตํ ๋๊ฐ ์์ต๋๋ค! ๐ [์ฌ์ง]์ธํ์ฝ 2023 'ํ์ ์คํฌ๋ฆฝํธ๋ ์ ๊ทธ๋ด๊น?' ๋ฐํ์์ ๊ฐ์์ ๋๋ค. ๐ง ๋ฐฐ์
www.inflearn.com