Typescript, JavaScript: איך ליצור סוג משולב בצורה דינמית באמצעות לולאת typeof?
נניח שיש לנו:
const array = [a, b, c] // could be any number of items in here
type T = ??? // how to write this?
כך שהתוצאה שווה ל
type T = typeof a & typeof b & typeof c
למעט ש-T נוצר באופן דינמי בהתבסס על לולאה דרך array (מאחר ש-array עשוי למעשה להכיל פריטים אחרים מלבד a, b, c). פתרון המשתמש בממשקים עשוי להיות מקובל גם כן.
תשובה #1
אם המערך מקבל טיפוס נכון, הוא יקבל טיפוס כאיחוד של טיפוסי הפריטים. לדוגמה:
let a = { aProp: 1 };
let b = { bProp: 1 };
let c = { cProp: 1 };
const array = [a, b, c] // typed as ({ aProp: number; } | { bProp: number; } | { cProp: number; })[]
מתחילים מזה, אנחנו יכולים להפוך את האיחוד לחיתוך באמצעות סוגים מותנים (ראה תשובה זו להסבר על UnionToIntersection) ולהשתמש בשאילתת סוג כדי לקבל את סוגו של פריט במערך:
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
type T = UnionToIntersection<typeof array[number]> // { aProp: number; } & { bProp: number; } & { cProp: number; }
תשובה #2
סוגי Typescript קיימים רק בזמן הקומפילציה, הם יוסרו בזמן הריצה (מה שהופך את זה ל-JavaScript). מכיוון שהערכים של המערך קיימים רק בזמן הריצה, אין דרך לקבל את הסוג שלהם בזמן הקומפילציה.
