1/**
2 * TypeScript μΈν°νμ΄μ€μ μ λ€λ¦
3 * - μΈν°νμ΄μ€
4 * - ν΄λμ€μ νμ
5 * - μ λ€λ¦
6 * - μ νΈλ¦¬ν° νμ
7 */
8
9// ============================================
10// 1. μΈν°νμ΄μ€ κΈ°μ΄
11// ============================================
12
13interface User {
14 id: number;
15 name: string;
16 email: string;
17 age?: number; // μ νμ μμ±
18 readonly createdAt: Date; // μ½κΈ° μ μ©
19}
20
21const user1: User = {
22 id: 1,
23 name: "νκΈΈλ",
24 email: "hong@example.com",
25 createdAt: new Date()
26};
27
28// user1.createdAt = new Date(); // μλ¬: readonly
29
30console.log("=== μΈν°νμ΄μ€ κΈ°μ΄ ===");
31console.log(`μ¬μ©μ: ${user1.name} (${user1.email})`);
32
33// ============================================
34// 2. μΈν°νμ΄μ€ νμ₯
35// ============================================
36
37interface Person {
38 name: string;
39 age: number;
40}
41
42interface Employee extends Person {
43 employeeId: string;
44 department: string;
45}
46
47interface Manager extends Employee {
48 teamSize: number;
49 reports: Employee[];
50}
51
52const manager: Manager = {
53 name: "κΉλΆμ₯",
54 age: 45,
55 employeeId: "E001",
56 department: "κ°λ°ν",
57 teamSize: 5,
58 reports: []
59};
60
61console.log("\n=== μΈν°νμ΄μ€ νμ₯ ===");
62console.log(`λ§€λμ : ${manager.name}, ${manager.department}, νμ ${manager.teamSize}λͺ
`);
63
64// ============================================
65// 3. μΈν°νμ΄μ€ λ³ν©
66// ============================================
67
68interface Config {
69 apiUrl: string;
70}
71
72interface Config {
73 timeout: number;
74}
75
76// λ μ μΈμ΄ μλμΌλ‘ λ³ν©λ¨
77const config: Config = {
78 apiUrl: "https://api.example.com",
79 timeout: 5000
80};
81
82console.log("\n=== μΈν°νμ΄μ€ λ³ν© ===");
83console.log(`Config: ${config.apiUrl}, timeout: ${config.timeout}ms`);
84
85// ============================================
86// 4. ν¨μ μΈν°νμ΄μ€
87// ============================================
88
89interface MathFunc {
90 (x: number, y: number): number;
91}
92
93interface Calculator {
94 add: MathFunc;
95 subtract: MathFunc;
96 multiply: MathFunc;
97 divide: MathFunc;
98}
99
100const calculator: Calculator = {
101 add: (x, y) => x + y,
102 subtract: (x, y) => x - y,
103 multiply: (x, y) => x * y,
104 divide: (x, y) => x / y
105};
106
107console.log("\n=== ν¨μ μΈν°νμ΄μ€ ===");
108console.log(`10 + 5 = ${calculator.add(10, 5)}`);
109console.log(`10 - 5 = ${calculator.subtract(10, 5)}`);
110
111// ============================================
112// 5. μΈλ±μ€ μκ·Έλμ²
113// ============================================
114
115interface StringDictionary {
116 [key: string]: string;
117}
118
119interface NumberArray {
120 [index: number]: string;
121}
122
123const translations: StringDictionary = {
124 hello: "μλ
νμΈμ",
125 goodbye: "μλ
ν κ°μΈμ",
126 thanks: "κ°μ¬ν©λλ€"
127};
128
129const colors: NumberArray = ["red", "green", "blue"];
130
131console.log("\n=== μΈλ±μ€ μκ·Έλμ² ===");
132console.log(`hello = ${translations["hello"]}`);
133console.log(`colors[0] = ${colors[0]}`);
134
135// ============================================
136// 6. ν΄λμ€μ μΈν°νμ΄μ€
137// ============================================
138
139interface Animal {
140 name: string;
141 makeSound(): void;
142}
143
144interface Movable {
145 move(distance: number): void;
146}
147
148class Dog implements Animal, Movable {
149 constructor(public name: string) {}
150
151 makeSound(): void {
152 console.log(`${this.name}: λ©λ©!`);
153 }
154
155 move(distance: number): void {
156 console.log(`${this.name}μ΄(κ°) ${distance}m μ΄λνμ΅λλ€.`);
157 }
158}
159
160console.log("\n=== ν΄λμ€μ μΈν°νμ΄μ€ ===");
161const dog = new Dog("λ°λμ΄");
162dog.makeSound();
163dog.move(10);
164
165// ============================================
166// 7. μ λ€λ¦ κΈ°μ΄
167// ============================================
168
169// μ λ€λ¦ ν¨μ
170function identity<T>(arg: T): T {
171 return arg;
172}
173
174// μ λ€λ¦ λ°°μ΄ ν¨μ
175function firstElement<T>(arr: T[]): T | undefined {
176 return arr[0];
177}
178
179// μ λ€λ¦ κ°μ²΄ ν¨μ
180function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
181 return obj[key];
182}
183
184console.log("\n=== μ λ€λ¦ κΈ°μ΄ ===");
185console.log(`identity("hello"): ${identity("hello")}`);
186console.log(`identity(42): ${identity(42)}`);
187console.log(`firstElement([1,2,3]): ${firstElement([1, 2, 3])}`);
188
189const person = { name: "νκΈΈλ", age: 25 };
190console.log(`getProperty: ${getProperty(person, "name")}`);
191
192// ============================================
193// 8. μ λ€λ¦ μΈν°νμ΄μ€
194// ============================================
195
196interface ApiResponse<T> {
197 data: T;
198 status: number;
199 message: string;
200}
201
202interface UserData {
203 id: number;
204 name: string;
205}
206
207interface ProductData {
208 id: number;
209 title: string;
210 price: number;
211}
212
213const userResponse: ApiResponse<UserData> = {
214 data: { id: 1, name: "νκΈΈλ" },
215 status: 200,
216 message: "Success"
217};
218
219const productResponse: ApiResponse<ProductData> = {
220 data: { id: 1, title: "λ
ΈνΈλΆ", price: 1000000 },
221 status: 200,
222 message: "Success"
223};
224
225console.log("\n=== μ λ€λ¦ μΈν°νμ΄μ€ ===");
226console.log(`User: ${userResponse.data.name}`);
227console.log(`Product: ${productResponse.data.title}`);
228
229// ============================================
230// 9. μ λ€λ¦ ν΄λμ€
231// ============================================
232
233class Stack<T> {
234 private items: T[] = [];
235
236 push(item: T): void {
237 this.items.push(item);
238 }
239
240 pop(): T | undefined {
241 return this.items.pop();
242 }
243
244 peek(): T | undefined {
245 return this.items[this.items.length - 1];
246 }
247
248 isEmpty(): boolean {
249 return this.items.length === 0;
250 }
251
252 size(): number {
253 return this.items.length;
254 }
255}
256
257console.log("\n=== μ λ€λ¦ ν΄λμ€ ===");
258const numberStack = new Stack<number>();
259numberStack.push(1);
260numberStack.push(2);
261numberStack.push(3);
262console.log(`Stack peek: ${numberStack.peek()}`);
263console.log(`Stack pop: ${numberStack.pop()}`);
264console.log(`Stack size: ${numberStack.size()}`);
265
266// ============================================
267// 10. μ λ€λ¦ μ μ½ μ‘°κ±΄
268// ============================================
269
270interface HasLength {
271 length: number;
272}
273
274function logLength<T extends HasLength>(arg: T): number {
275 console.log(`κΈΈμ΄: ${arg.length}`);
276 return arg.length;
277}
278
279console.log("\n=== μ λ€λ¦ μ μ½ μ‘°κ±΄ ===");
280logLength("Hello"); // stringμ length μμ
281logLength([1, 2, 3, 4]); // arrayλ length μμ
282logLength({ length: 10 }); // κ°μ²΄λ κ°λ₯
283
284// ============================================
285// 11. μ νΈλ¦¬ν° νμ
286// ============================================
287
288interface Todo {
289 title: string;
290 description: string;
291 completed: boolean;
292 createdAt: Date;
293}
294
295// Partial<T>: λͺ¨λ μμ±μ μ νμ μΌλ‘
296type PartialTodo = Partial<Todo>;
297
298// Required<T>: λͺ¨λ μμ±μ νμλ‘
299type RequiredTodo = Required<Todo>;
300
301// Readonly<T>: λͺ¨λ μμ±μ μ½κΈ° μ μ©μΌλ‘
302type ReadonlyTodo = Readonly<Todo>;
303
304// Pick<T, K>: νΉμ μμ±λ§ μ ν
305type TodoPreview = Pick<Todo, "title" | "completed">;
306
307// Omit<T, K>: νΉμ μμ± μ μΈ
308type TodoWithoutDate = Omit<Todo, "createdAt">;
309
310// Record<K, T>: ν€-κ° νμ
μ μ
311type PageInfo = Record<"home" | "about" | "contact", { title: string }>;
312
313const pages: PageInfo = {
314 home: { title: "ν" },
315 about: { title: "μκ°" },
316 contact: { title: "μ°λ½μ²" }
317};
318
319console.log("\n=== μ νΈλ¦¬ν° νμ
===");
320
321const partialTodo: PartialTodo = {
322 title: "μΌλΆλ§"
323};
324
325const todoPreview: TodoPreview = {
326 title: "미리보기",
327 completed: false
328};
329
330console.log(`PartialTodo: ${JSON.stringify(partialTodo)}`);
331console.log(`TodoPreview: ${JSON.stringify(todoPreview)}`);
332console.log(`Pages: ${Object.keys(pages).join(", ")}`);
333
334// ============================================
335// 12. μ‘°κ±΄λΆ νμ
336// ============================================
337
338type IsString<T> = T extends string ? "yes" : "no";
339
340type A = IsString<string>; // "yes"
341type B = IsString<number>; // "no"
342
343// infer ν€μλ
344type GetReturnType<T> = T extends (...args: any[]) => infer R ? R : never;
345
346type FuncReturn = GetReturnType<() => number>; // number
347type AsyncReturn = GetReturnType<() => Promise<string>>; // Promise<string>
348
349// Exclude, Extract
350type T1 = Exclude<"a" | "b" | "c", "a">; // "b" | "c"
351type T2 = Extract<"a" | "b" | "c", "a" | "f">; // "a"
352
353// NonNullable
354type T3 = NonNullable<string | null | undefined>; // string
355
356console.log("\n=== μ‘°κ±΄λΆ νμ
===");
357console.log("IsString<string> = 'yes'");
358console.log("IsString<number> = 'no'");
359console.log("Exclude<'a'|'b'|'c', 'a'> = 'b' | 'c'");
360
361// ============================================
362// 13. λ§€νλ νμ
363// ============================================
364
365type Nullable<T> = {
366 [P in keyof T]: T[P] | null;
367};
368
369type Optional<T> = {
370 [P in keyof T]?: T[P];
371};
372
373type Getters<T> = {
374 [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P];
375};
376
377interface Point {
378 x: number;
379 y: number;
380}
381
382type NullablePoint = Nullable<Point>; // { x: number | null; y: number | null }
383type PointGetters = Getters<Point>; // { getX: () => number; getY: () => number }
384
385console.log("\n=== λ§€νλ νμ
===");
386const nullablePoint: NullablePoint = { x: 10, y: null };
387console.log(`NullablePoint: x=${nullablePoint.x}, y=${nullablePoint.y}`);
388
389// ============================================
390// 14. ν
νλ¦Ώ 리ν°λ΄ νμ
391// ============================================
392
393type EventName = "click" | "scroll" | "mousemove";
394type Handler = `on${Capitalize<EventName>}`; // "onClick" | "onScroll" | "onMousemove"
395
396type Greeting = `Hello, ${string}!`;
397
398const greeting: Greeting = "Hello, World!";
399
400console.log("\n=== ν
νλ¦Ώ 리ν°λ΄ νμ
===");
401console.log(`Greeting: ${greeting}`);
402console.log("Handler νμ
: 'onClick' | 'onScroll' | 'onMousemove'");
403
404// ============================================
405// μ€ν μμ
406// ============================================
407console.log("\n=== TypeScript μΈν°νμ΄μ€/μ λ€λ¦ μλ£ ===");
408console.log("μ»΄νμΌ: npx tsc interfaces.ts");
409console.log("μ€ν: node interfaces.js");