Utility Types

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

type User = {
    id: number;
    name: string;
    email: string;
    passwordHash: string;
    createdAt: Date;
};

Partial ו-Required

// כל השדות אופציונליים: מושלם לעדכון חלקי
function updateUser(id: number, changes: Partial<User>) { /* ... */ }

updateUser(1, { name: 'דנה כהן' });   // ✅ לא צריך את כל השדות

// ההפך: כל השדות חובה
type Settings = { theme?: string; language?: string };
const defaults: Required<Settings> = { theme: 'light', language: 'he' };

Pick ו-Omit

// רק שדות מסוימים
type UserPreview = Pick<User, 'id' | 'name'>;

// כל השדות חוץ מ...
type PublicUser = Omit<User, 'passwordHash'>;   // מה שמותר לשלוח ללקוח

// הנתונים ליצירת משתמש: בלי מה שהשרת ממלא לבד
type NewUser = Omit<User, 'id' | 'createdAt' | 'passwordHash'> & { password: string };

היתרון הגדול: מוסיפים שדה ל-User, וכל הטיפוסים הנגזרים מתעדכנים לבד.

Readonly

function printUser(user: Readonly<User>) {
    user.name = 'x';
    // Cannot assign to 'name' because it is a read-only property.
}

Record

type Status = 'draft' | 'published' | 'archived';

const statusColors: Record<Status, string> = {
    draft: 'gray',
    published: 'green',
    archived: 'red',
};

ReturnType, Parameters ו-Awaited

function createStore() {
    return { items: [] as string[], add(item: string) { /* ... */ } };
}

type Store = ReturnType<typeof createStore>;          // הטיפוס שהפונקציה מחזירה
type AddParams = Parameters<Store['add']>;             // [item: string]

type UserResult = Awaited<ReturnType<typeof fetchUser>>;   // User, בלי ה-Promise

שימושי במיוחד כשהטיפוס מגיע מקוד שלא אתם כתבתם, ואין לו שם מיוצא.

Exclude, Extract ו-NonNullable

type Role = 'admin' | 'editor' | 'viewer';

type Staff = Exclude<Role, 'viewer'>;          // 'admin' | 'editor'
type OnlyAdmin = Extract<Role, 'admin'>;       // 'admin'
type Name = NonNullable<string | null | undefined>;   // string

satisfies: לבדוק בלי לאבד פרטים

type Theme = Record<string, string>;

// עם : Theme היינו מאבדים את שמות המפתחות
const colors = {
    primary: '#4f46e5',
    danger: '#dc2626',
} satisfies Theme;

colors.primary;    // ✅ TypeScript זוכרת שהמפתח קיים
colors.success;
// Property 'success' does not exist on type ...

satisfies בודק שהערך מתאים לטיפוס, אבל משאיר את הטיפוס המדויק שהוסק. אחד הכלים החדשים (TypeScript 4.9) והשימושיים ביותר.

סיכום

צריךמשתמשים ב-
עדכון חלקיPartial<T>
גרסה בלי שדות רגישיםOmit<T, K>
רק כמה שדותPick<T, K>
מילון עם מפתחות ידועיםRecord<K, V>
טיפוס מתוך פונקציה קיימתReturnType, Parameters, Awaited

בדקו את עצמכם

נסו לענות לבד לפני שאתם פותחים את התשובה.

  1. איך מקבלים את User בלי השדה passwordHash?

    1. Pick<User, 'passwordHash'>
    2. Remove<User>
    3. Partial<User>
    4. Omit<User, 'passwordHash'>
    הצגת התשובה

    תשובה ד. Omit מסיר שדות, Pick משאיר רק את השדות שנבחרו.

  2. לאיזה צורך מתאים Partial<T>?

    1. מילון
    2. מחיקה
    3. עדכון חלקי: כל השדות הופכים לאופציונליים
    4. קריאה בלבד
    הצגת התשובה

    תשובה ג. למשל updateUser(id, { name: 'חדש' }).

  3. מה עושה satisfies?

    1. ממיר טיפוס
    2. בודק שהערך מתאים לטיפוס, בלי לאבד את הטיפוס המדויק שהוסק
    3. מכבה את הבדיקה
    4. יוצר enum
    הצגת התשובה

    תשובה ב. שונה מ-: Type, שמחליף את הטיפוס המוסק בטיפוס הכללי.