basics.ts

Download
typescript 316 lines 8.4 KB
  1/**
  2 * TypeScript ๊ธฐ์ดˆ
  3 * - ๊ธฐ๋ณธ ํƒ€์ž…
  4 * - ํƒ€์ž… ์ถ”๋ก 
  5 * - ์œ ๋‹ˆ์˜จ/๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž…
  6 * - ํƒ€์ž… ๊ฐ€๋“œ
  7 */
  8
  9// ============================================
 10// 1. ๊ธฐ๋ณธ ํƒ€์ž…
 11// ============================================
 12
 13// ์›์‹œ ํƒ€์ž…
 14const name: string = "ํ™๊ธธ๋™";
 15const age: number = 25;
 16const isActive: boolean = true;
 17const nothing: null = null;
 18const notDefined: undefined = undefined;
 19
 20// ๋ฐฐ์—ด
 21const numbers: number[] = [1, 2, 3, 4, 5];
 22const names: Array<string> = ["Alice", "Bob", "Charlie"];
 23
 24// ํŠœํ”Œ (๊ณ ์ •๋œ ๊ธธ์ด์™€ ํƒ€์ž…)
 25const person: [string, number] = ["ํ™๊ธธ๋™", 25];
 26const rgb: [number, number, number] = [255, 128, 0];
 27
 28// ๊ฐ์ฒด
 29const user: { name: string; age: number; email?: string } = {
 30    name: "๊น€์ฒ ์ˆ˜",
 31    age: 30,
 32    // email์€ ์„ ํƒ์ (optional)
 33};
 34
 35console.log("=== ๊ธฐ๋ณธ ํƒ€์ž… ===");
 36console.log(`์ด๋ฆ„: ${name}, ๋‚˜์ด: ${age}, ํ™œ์„ฑ: ${isActive}`);
 37console.log(`์ˆซ์ž ๋ฐฐ์—ด: ${numbers.join(", ")}`);
 38console.log(`ํŠœํ”Œ: ${person[0]}(${person[1]}์„ธ)`);
 39
 40// ============================================
 41// 2. ํƒ€์ž… ์ถ”๋ก  (Type Inference)
 42// ============================================
 43
 44// TypeScript๊ฐ€ ํƒ€์ž…์„ ์ž๋™์œผ๋กœ ์ถ”๋ก 
 45let inferredString = "Hello";  // string์œผ๋กœ ์ถ”๋ก 
 46let inferredNumber = 42;       // number๋กœ ์ถ”๋ก 
 47let inferredArray = [1, 2, 3]; // number[]๋กœ ์ถ”๋ก 
 48
 49// ํ•จ์ˆ˜ ๋ฐ˜ํ™˜ ํƒ€์ž… ์ถ”๋ก 
 50function add(a: number, b: number) {
 51    return a + b;  // number ๋ฐ˜ํ™˜์œผ๋กœ ์ถ”๋ก 
 52}
 53
 54const sum = add(10, 20);  // sum์€ number๋กœ ์ถ”๋ก 
 55
 56console.log("\n=== ํƒ€์ž… ์ถ”๋ก  ===");
 57console.log(`์ถ”๋ก ๋œ ํ•ฉ๊ณ„: ${sum}`);
 58
 59// ============================================
 60// 3. ์œ ๋‹ˆ์˜จ ํƒ€์ž… (Union Types)
 61// ============================================
 62
 63// ์—ฌ๋Ÿฌ ํƒ€์ž… ์ค‘ ํ•˜๋‚˜
 64type StringOrNumber = string | number;
 65
 66function printId(id: StringOrNumber) {
 67    console.log(`ID: ${id}`);
 68
 69    // ํƒ€์ž…์— ๋”ฐ๋ฅธ ์ฒ˜๋ฆฌ
 70    if (typeof id === "string") {
 71        console.log(`  (๋ฌธ์ž์—ด, ๊ธธ์ด: ${id.length})`);
 72    } else {
 73        console.log(`  (์ˆซ์ž, 2๋ฐฐ: ${id * 2})`);
 74    }
 75}
 76
 77console.log("\n=== ์œ ๋‹ˆ์˜จ ํƒ€์ž… ===");
 78printId("user_123");
 79printId(42);
 80
 81// ============================================
 82// 4. ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž… (Literal Types)
 83// ============================================
 84
 85// ํŠน์ • ๊ฐ’๋งŒ ํ—ˆ์šฉ
 86type Direction = "up" | "down" | "left" | "right";
 87type DiceValue = 1 | 2 | 3 | 4 | 5 | 6;
 88
 89function move(direction: Direction) {
 90    console.log(`Moving ${direction}`);
 91}
 92
 93function rollDice(): DiceValue {
 94    return Math.ceil(Math.random() * 6) as DiceValue;
 95}
 96
 97console.log("\n=== ๋ฆฌํ„ฐ๋Ÿด ํƒ€์ž… ===");
 98move("up");
 99move("left");
100console.log(`์ฃผ์‚ฌ์œ„: ${rollDice()}`);
101
102// ============================================
103// 5. any, unknown, never
104// ============================================
105
106// any: ๋ชจ๋“  ํƒ€์ž… ํ—ˆ์šฉ (ํƒ€์ž… ์ฒดํฌ ๋น„ํ™œ์„ฑํ™”, ์‚ฌ์šฉ ์ž์ œ)
107let anything: any = "hello";
108anything = 42;
109anything = true;
110
111// unknown: ๋ชจ๋“  ํƒ€์ž… ํ—ˆ์šฉ, ์‚ฌ์šฉ ์‹œ ํƒ€์ž… ์ฒดํฌ ํ•„์š”
112let unknownValue: unknown = "hello";
113
114// unknown์€ ๋ฐ”๋กœ ์‚ฌ์šฉ ๋ถˆ๊ฐ€, ํƒ€์ž… ํ™•์ธ ํ•„์š”
115if (typeof unknownValue === "string") {
116    console.log(`unknown ๊ฐ’: ${unknownValue.toUpperCase()}`);
117}
118
119// never: ์ ˆ๋Œ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ํƒ€์ž…
120function throwError(message: string): never {
121    throw new Error(message);
122}
123
124function infiniteLoop(): never {
125    while (true) {
126        // ๋ฌดํ•œ ๋ฃจํ”„
127    }
128}
129
130console.log("\n=== any, unknown ===");
131console.log(`any ๊ฐ’: ${anything}`);
132
133// ============================================
134// 6. ํƒ€์ž… ๋ณ„์นญ (Type Alias)
135// ============================================
136
137type Point = {
138    x: number;
139    y: number;
140};
141
142type ID = string | number;
143
144type UserRole = "admin" | "editor" | "viewer";
145
146type UserProfile = {
147    id: ID;
148    name: string;
149    role: UserRole;
150    location: Point;
151};
152
153const admin: UserProfile = {
154    id: "admin_001",
155    name: "๊ด€๋ฆฌ์ž",
156    role: "admin",
157    location: { x: 0, y: 0 }
158};
159
160console.log("\n=== ํƒ€์ž… ๋ณ„์นญ ===");
161console.log(`์‚ฌ์šฉ์ž: ${admin.name} (${admin.role})`);
162
163// ============================================
164// 7. ํƒ€์ž… ๊ฐ€๋“œ (Type Guards)
165// ============================================
166
167type Circle = { kind: "circle"; radius: number };
168type Rectangle = { kind: "rectangle"; width: number; height: number };
169type Shape = Circle | Rectangle;
170
171// ํŒ๋ณ„ ์œ ๋‹ˆ์˜จ (Discriminated Union)
172function getArea(shape: Shape): number {
173    switch (shape.kind) {
174        case "circle":
175            return Math.PI * shape.radius ** 2;
176        case "rectangle":
177            return shape.width * shape.height;
178    }
179}
180
181// in ์—ฐ์‚ฐ์ž๋กœ ํƒ€์ž… ๊ฐ€๋“œ
182function printShape(shape: Shape) {
183    if ("radius" in shape) {
184        console.log(`์›: ๋ฐ˜์ง€๋ฆ„ ${shape.radius}`);
185    } else {
186        console.log(`์‚ฌ๊ฐํ˜•: ${shape.width} x ${shape.height}`);
187    }
188}
189
190console.log("\n=== ํƒ€์ž… ๊ฐ€๋“œ ===");
191const circle: Circle = { kind: "circle", radius: 5 };
192const rect: Rectangle = { kind: "rectangle", width: 10, height: 20 };
193
194console.log(`์› ๋ฉด์ : ${getArea(circle).toFixed(2)}`);
195console.log(`์‚ฌ๊ฐํ˜• ๋ฉด์ : ${getArea(rect)}`);
196printShape(circle);
197printShape(rect);
198
199// ============================================
200// 8. ํƒ€์ž… ๋‹จ์–ธ (Type Assertion)
201// ============================================
202
203// as ํ‚ค์›Œ๋“œ๋กœ ํƒ€์ž… ๋‹จ์–ธ
204const input = document.getElementById("myInput") as HTMLInputElement;
205// ๋˜๋Š” angle-bracket ๋ฌธ๋ฒ• (JSX์—์„œ ์‚ฌ์šฉ ๋ถˆ๊ฐ€)
206// const input = <HTMLInputElement>document.getElementById("myInput");
207
208// ์ฃผ์˜: ํƒ€์ž… ๋‹จ์–ธ์€ ๋Ÿฐํƒ€์ž„์— ์˜ํ–ฅ ์—†์Œ
209const maybeString: unknown = "hello world";
210const strLength = (maybeString as string).length;
211
212console.log("\n=== ํƒ€์ž… ๋‹จ์–ธ ===");
213console.log(`๋ฌธ์ž์—ด ๊ธธ์ด: ${strLength}`);
214
215// ============================================
216// 9. ํ•จ์ˆ˜ ํƒ€์ž…
217// ============================================
218
219// ํ•จ์ˆ˜ ํƒ€์ž… ์ •์˜
220type MathOperation = (a: number, b: number) => number;
221
222const multiply: MathOperation = (a, b) => a * b;
223const divide: MathOperation = (a, b) => a / b;
224
225// ์„ ํƒ์  ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ๊ธฐ๋ณธ๊ฐ’
226function greet(name: string, greeting: string = "์•ˆ๋…•ํ•˜์„ธ์š”"): string {
227    return `${greeting}, ${name}๋‹˜!`;
228}
229
230// ๋‚˜๋จธ์ง€ ๋งค๊ฐœ๋ณ€์ˆ˜
231function sumAll(...numbers: number[]): number {
232    return numbers.reduce((acc, cur) => acc + cur, 0);
233}
234
235// ์˜ค๋ฒ„๋กœ๋“œ ์‹œ๊ทธ๋‹ˆ์ฒ˜
236function format(value: string): string;
237function format(value: number): string;
238function format(value: string | number): string {
239    if (typeof value === "string") {
240        return value.toUpperCase();
241    } else {
242        return value.toFixed(2);
243    }
244}
245
246console.log("\n=== ํ•จ์ˆ˜ ํƒ€์ž… ===");
247console.log(`๊ณฑ์…ˆ: 3 * 4 = ${multiply(3, 4)}`);
248console.log(`๋‚˜๋ˆ—์…ˆ: 10 / 3 = ${divide(10, 3).toFixed(2)}`);
249console.log(greet("ํ™๊ธธ๋™"));
250console.log(greet("๊น€์ฒ ์ˆ˜", "๋ฐ˜๊ฐ‘์Šต๋‹ˆ๋‹ค"));
251console.log(`ํ•ฉ๊ณ„: ${sumAll(1, 2, 3, 4, 5)}`);
252console.log(`๋ฌธ์ž์—ด ํฌ๋งท: ${format("hello")}`);
253console.log(`์ˆซ์ž ํฌ๋งท: ${format(3.14159)}`);
254
255// ============================================
256// 10. ์—ด๊ฑฐํ˜• (Enum)
257// ============================================
258
259// ์ˆซ์ž ์—ด๊ฑฐํ˜•
260enum Direction2 {
261    Up = 1,
262    Down,
263    Left,
264    Right
265}
266
267// ๋ฌธ์ž์—ด ์—ด๊ฑฐํ˜•
268enum HttpStatus {
269    OK = "OK",
270    NotFound = "NOT_FOUND",
271    ServerError = "SERVER_ERROR"
272}
273
274// const enum (์ธ๋ผ์ธ๋จ)
275const enum Color {
276    Red = "#ff0000",
277    Green = "#00ff00",
278    Blue = "#0000ff"
279}
280
281console.log("\n=== ์—ด๊ฑฐํ˜• ===");
282console.log(`Direction.Up: ${Direction2.Up}`);
283console.log(`Direction.Right: ${Direction2.Right}`);
284console.log(`HttpStatus.OK: ${HttpStatus.OK}`);
285console.log(`Color.Red: ${Color.Red}`);
286
287// ============================================
288// 11. Null ์ฒดํฌ
289// ============================================
290
291// strictNullChecks๊ฐ€ ํ™œ์„ฑํ™”๋œ ๊ฒฝ์šฐ
292function processValue(value: string | null | undefined) {
293    // ์˜ต์…”๋„ ์ฒด์ด๋‹
294    const length = value?.length;
295
296    // Nullish ๋ณ‘ํ•ฉ
297    const defaulted = value ?? "๊ธฐ๋ณธ๊ฐ’";
298
299    // Non-null ๋‹จ์–ธ (ํ™•์‹คํ•  ๋•Œ๋งŒ ์‚ฌ์šฉ)
300    // const definite = value!.length;
301
302    console.log(`๊ธธ์ด: ${length}, ๊ฐ’: ${defaulted}`);
303}
304
305console.log("\n=== Null ์ฒดํฌ ===");
306processValue("hello");
307processValue(null);
308processValue(undefined);
309
310// ============================================
311// ์‹คํ–‰ ์˜ˆ์‹œ
312// ============================================
313console.log("\n=== TypeScript ๊ธฐ์ดˆ ์™„๋ฃŒ ===");
314console.log("์ปดํŒŒ์ผ: npx tsc basics.ts");
315console.log("์‹คํ–‰: node basics.js");