לדלג לתוכן

5.5 טיפוסי איחוד וחיתוך תרגול

תרגול - טיפוסי איחוד וחיתוך

תרגיל 1 - union types בסיסיים

א. הגדירו טיפוס Input שיכול להיות string, number, או boolean. כתבו פונקציה describeInput שמקבלת Input ומחזירה מחרוזת שמתארת את הטיפוס והערך: "string: hello", "number: 42", "boolean: true".

ב. הגדירו טיפוס Nullish<T> שהוא T | null | undefined. כתבו פונקציה unwrap שמקבלת Nullish<string> וערך ברירת מחדל, ומחזירה את הערך אם הוא קיים, או את ברירת המחדל אם הוא null/undefined.

ג. הגדירו טיפוס StringOrArray שהוא string | string[]. כתבו פונקציה toArray שמקבלת StringOrArray ותמיד מחזירה string[] (אם קיבלה מחרוזת בודדת, עוטפת אותה במערך).

תרגיל 2 - literal types

א. הגדירו טיפוס Suit לחליפות קלפים: "hearts", "diamonds", "clubs", "spades". הגדירו טיפוס Rank לדרגות: מספרים 2-10 ו-"J", "Q", "K", "A".

ב. הגדירו אינטרפייס Card עם suit: Suit ו-rank: Rank.

ג. כתבו פונקציה getCardValue שמקבלת Card ומחזירה את הערך המספרי: מספרים כערכם, J/Q/K שווים 10, A שווה 11.

ד. כתבו פונקציה formatCard שמקבלת Card ומחזירה מחרוזת: "A of hearts", "10 of spades".

תרגיל 3 - discriminated unions - תשלומים

הגדירו מערכת תשלומים עם discriminated union:

  • CreditCardPayment - method: "creditCard", cardNumber: string, expiryDate: string, cvv: string
  • PayPalPayment - method: "paypal", email: string
  • BankTransferPayment - method: "bankTransfer", bankName: string, accountNumber: string, routingNumber: string
  • CryptoPayment - method: "crypto", walletAddress: string, currency: "BTC" | "ETH" | "USDT"

א. הגדירו את הטיפוסים ואת ה-union type Payment.

ב. כתבו פונקציה getPaymentSummary שמקבלת Payment ומחזירה תיאור מקוצר (למשל: "Credit card ending in 1234", "PayPal: user@example.com"). אל תחשפו מידע רגיש מלא.

ג. כתבו פונקציה getProcessingFee שמקבלת Payment ו-amount: number ומחזירה את עמלת העיבוד: כרטיס אשראי 2.9%, PayPal 3.5%, העברה בנקאית 1%, קריפטו 0.5%.

ד. הוסיפו exhaustive checking ל-getPaymentSummary.

תרגיל 4 - דפוס Result

א. הגדירו טיפוס גנרי Result<T> שהוא discriminated union:
- { success: true; value: T }
- { success: false; error: string }

ב. כתבו פונקציה parseJSON שמקבלת מחרוזת ומחזירה Result<unknown>. אם ה-parse מצליח, מחזירה success עם הנתונים. אם נכשל, מחזירה failure עם הודעת השגיאה.

ג. כתבו פונקציה divide שמקבלת שני מספרים ומחזירה Result<number>. חלוקה באפס מחזירה failure.

ד. כתבו פונקציה chain שמקבלת Result<T> ופונקציה (value: T) => Result<U>, ומחזירה Result<U>. אם ה-input הוא failure, מחזירה failure מיד בלי להפעיל את הפונקציה.

תרגיל 5 - intersection types

א. הגדירו שלושה טיפוסים:
- Identifiable - עם id: string
- Timestamped - עם createdAt: Date ו-updatedAt: Date
- Ownable - עם ownerId: string ו-ownerName: string

ב. השתמשו ב-intersection כדי ליצור:
- Document = בסיס (title: string, content: string) + Identifiable + Timestamped + Ownable
- Comment = בסיס (text: string, parentId: string) + Identifiable + Timestamped
- Tag = בסיס (name: string, color: string) + Identifiable

ג. כתבו פונקציה getAge שמקבלת Timestamped (לא Document ולא Comment - את ה-trait עצמו) ומחזירה את מספר הימים מאז ה-createdAt.

תרגיל 6 - מכונת מצבים - נגן מדיה

הגדירו את המצבים של נגן מדיה:

  • Stopped - state: "stopped"
  • Playing - state: "playing", track: string, position: number (seconds), volume: number (0-100)
  • Paused - state: "paused", track: string, position: number, volume: number
  • Buffering - state: "buffering", track: string, progress: number (0-100)

א. הגדירו את ה-discriminated union PlayerState.

ב. כתבו פונקציה getPlayerDisplay שמקבלת PlayerState ומחזירה מחרוזת שמתארת את המצב הנוכחי.

ג. כתבו פונקציה handlePlayerAction שמקבלת PlayerState ופעולה (discriminated union עם type: "play", "pause", "stop", "seek") ומחזירה PlayerState חדש. חשבו על כל המעברים האפשריים - לדוגמה, אי אפשר לעשות seek כשה-player ב-stopped.

תרגיל 7 - מערכת הודעות - שילוב union עם intersection

בנו מערכת הודעות לאפליקציית צ׳אט:

הגדירו טיפוס בסיס BaseMessage עם id: string, timestamp: number, senderId: string.

הגדירו discriminated union של סוגי הודעות (כל אחד הוא intersection עם BaseMessage):

  • TextMessage - type: "text", content: string
  • ImageMessage - type: "image", url: string, width: number, height: number, caption?: string
  • FileMessage - type: "file", fileName: string, fileSize: number, mimeType: string
  • SystemMessage - type: "system", action: "join" | "leave" | "rename", details: string

א. הגדירו את כל הטיפוסים ואת ה-union ChatMessage.

ב. כתבו פונקציה renderMessage שמחזירה HTML string לכל סוג הודעה.

ג. כתבו פונקציה searchMessages שמקבלת מערך של ChatMessage ומחרוזת חיפוש, ומחזירה את כל ההודעות שמכילות את מחרוזת החיפוש (ב-content, caption, fileName, או details - לפי הסוג).

ד. כתבו פונקציה getMessageStats שמקבלת מערך של ChatMessage ומחזירה אובייקט עם סטטיסטיקות: כמה הודעות מכל סוג, גודל קבצים כולל, מספר תמונות.