Skip to content

צמצום טיפוסים ב-TypeScript מוסבר

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

צמצום הוא האופן שבו TypeScript הופך טיפוס רחב לטיפוס מצומצם יותר בתוך ענף קוד, כדי להוכיח שגישה למאפיין בטוחה. כל בדיקה (typeof, in, predicate, discriminator) אומרת למהדר: מכאן והלאה הערך ספציפי יותר. הטכניקות שלהלן הן ערכת העבודה.

טבלת עיון · 23 ערכים
23 of 23 rows
גארדים מובנים
מצמצם פרימיטיבים: string, number, boolean ועוד.if (typeof x === 'string') x.toUpperCase()
מצמצם למופע של מחלקה או של אובייקט בר-בנייה.if (e instanceof Error) e.message
מצמצם על ידי בדיקה שמאפיין קיים על הערך.if ('id' in obj) obj.id
מצמצם כל ערך למערך; מצמצם איחוד לחבר המערך שלו.if (Array.isArray(x)) x.map(f)
גארדים מותאמים אישית
פונקציית predicate שהחזרתה מצמצמת את הארגומנט.function isUser(x): x is User { return !!x.id }
predicate יכול לצמצם לאיחוד של טיפוסים, לא רק לטיפוס בודד.function isKey(x): x is string | number
predicate הצטלבות שומר על טיפוס הקלט ומוסיף לו שדות.function hasId(x): x is x & { id: string }
פונקציית assertion שזורקת שגיאה אם x אינו הטיפוס.function assertUser(x): asserts x is User
איחודים מובחנים
מצמצם איחוד לפי שדה literal משותף, דרך switch או if.type E = { kind: 'a'; a: number } | { kind: 'b'; b: string }
כל case מצמצם לחבר אחד של האיחוד.switch (u.kind) { case 'a': u.a }
מצמצם איחוד ללא תג כשמאפיין קיים על חבר אחד בלבד.if ('b' in u) u.b
כל case הוא תנאי; ה-case שהתאים מצמצם את הערך.switch (true) { case typeof x === 'string': }
ענף ברירת המחדל מקצה את הערך ל-never ובכך מוכיח שה-switch ממצה.default: { const x: never = u }
שוויון וזרימה
מסיר null ו-undefined אחרי בדיקת שוויון.if (x === null) return; x.toFixed()
מסיר ערכי שקר (0, '', null, undefined, NaN).if (!x) return; // x is defined here
מאפיין משורשר truthy מוכיח שערך הבסיס קיים.if (user?.active) user.name
הצהרת non-null מסירה null ו-undefined בלי בדיקה.x!.toFixed(2)
השמה ודאית: מצהירה ש-x יקבל ערך לפני שקוראים אותו.let name!: string; init()
הצמצום חל בתוך הענף וגם אחרי return מוקדם.if (!arr) return; arr.map(...)
כינויים ודחייה
בוליאני const שמחזיק בדיקה מצמצם בכל מקום שבו בודקים אותו.const isStr = typeof x === 'string'; if (isStr) …
משתנה const שומר על הצמצום שלו בתוך closures שתופסות אותו.const s = get(); if (s) use(() => s.length)
החל מ-TS 5.4, let או פרמטר שומרים על הצמצום בתוך closures אחרי ההשמה האחרונה שלהם.let n: string | null = get(); if (n) use(() => n.length)
אי אפשר להשתמש ב-unknown עד שגארד מצמצם אותו לטיפוס אמיתי.if (typeof u === 'string') u.length