• בלוג
  • איך קוד מתקלקל (דוגמת טייפסקריפט + ריאקט)

איך קוד מתקלקל (דוגמת טייפסקריפט + ריאקט)

03/12/2022

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

type PinkProps = {
    page?: number;
    itemsPerPage?: number;
    items: Array<{ id: number, text: string }>;
};

function Pink({ page=1, itemsPerPage=25, items }: PinkProps) {
    // component implementation ...
}

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

type OrangeProps = Pick<PinkProps, "page"|"itemsPerPage"> & {
    items: Array<{ id: number, visible: boolean }>
};

function Orange({ page=1, itemsPerPage=25, items}: OrangeProps) {
    // component implementation ...
}

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

function isValid(item: OrangeProps['items'][number]) {
    // validate the item from orange props
}

עכשיו בואו נראה את כל הגדרות הטיפוסים במבט אחד:

type PinkProps = {
    page?: number;
    itemsPerPage?: number;
    items: Array<{ id: number, text: string }>;
};

type OrangeProps = Pick<PinkProps, "page"|"itemsPerPage"> & {
    items: Array<{ id: number, visible: boolean }>
};

function isValid(item: OrangeProps['items'][number]) {
    // validate the item from orange props
}

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

type Paginated = {
    page?: number;
    itemsPerPage?: number;
}

type TextItem = {
    id: number;
    text: string;
}

type ToggleItem = {
    id: number;
    visible: boolean;
}

type PinkProps = Paginated & {
    items: Array<TextItem>;
};

type OrangeProps = Paginated & {
    items: Array<ToggleItem>;
}

function isValid(item: ToggleItem) {
    // validate the item from orange props
}

function Pink({ page=1, itemsPerPage=25, items }: PinkProps) {}


function Orange({ page=1, itemsPerPage=25, items}: OrangeProps) {}

ארוך יותר, כן, אבל הרבה יותר ברור וקל להרחבה.

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