טייפסקריפט - טייפ מותנה
-
יש לי ספריית JavaScript שאני מתחזק, ואני רוצה ליצור קובץ טייפים (
index.d.ts
) עבור מי שרוצה להשתמש בה עם TypeScript.
נתקלתי בבעיה - פונקציה שמקבלת שני ארגומנטים, והטייפ של הארגומנט השני משתנה לפי הפרמטר הראשון.דוגמה מופשטת:
function doSomething (mode, data) { if (mode == 'add') { const { num } = data; return num + 1; } else if (mode == 'upper') { const { str } = data; return str.toUpperCase(); } }
הפונקציה מקבלת פרמטר
mode
ואובייקטdata
,
אם הפרמטר הראשון (mode
) הואadd
אז השני (data
) צריך להיות אובייקט עם פרופרטיnum
, ואם הפרמטרmode
הואupper
אזdata
צריך להיות אובייקט עם פרופרטיstr
.
אני לא רוצה לשלב את הארגומנטים לאובייקט אחד של mode ו-data, מכיוון שזה ישבור הרבה מאוד קוד קיים.לא הצלחתי למצוא מידע רלוונטי בגוגל, האם זה אפשרי בכלל?
אשמח לעזרה, תודה מראש. -
יש כזה דבר מותנה ברמת הטיפוסים, אבל אני חושב שבהכרח צריך שהתנאי יכול להתברר בזמן קמפול ולא בזמן ריצה.
למשל להתנות את הטיפסו לפי מס' הארגומנטים, הקמפול יכול להסיק על הקריאה לפונקציה איזה טיפוסיות היא דורשת..
אבל אם זה בזמן ריצה (תלוי מה ערכו של המשתנה), איבדנו את כל הפואנטה של הטיפוסיות.
הכי פשוט זה לעשות משתנה על שמתאים לשני המקרים, למשל במקרה שלך ככה:function doSomething (mode: string, data: {num: number, str: string}) {
-
@dovid כתב בטייפסקריפט - טייפ מותנה:
הכי פשוט זה לעשות משתנה על שמתאים לשני המקרים, למשל במקרה שלך ככה:
הבעיה שזה מוריד הרבה מהערך של הטייפים, כי אני לא רוצה שהטייפ של הdata יהיה אובייקט גדול עם כמה פורפרטי'ס אופציונליים, אלא שהטייפ יהיה אובייקט בדיוק עם מה שאפשר להעביר, ואז אם מעבירים לdata פרופרטי שלא מתאים לmode שנבחר טייפסקריפט יתריע מיד.
-
@dovid
לקחתי את הדוגמה הזו ובניתי ממנה את זה:
https://www.typescriptlang.org/play?#code/C4TwDgpgBAsiAq5oF4oG8CwAoKUCGAJgQFzoB2ArgLamVUBGEATgL4A0U2uFYkTpaAM7B+UYUwCWZAOYtsLANzYAZhTIBjYBID2ZKAW0BlbVQjAAFlOkAeeFAgAPYBDIFBUANYQQ25bARIHADS9k4ubv6IkADa8AC6AHwAFFTaBBCk8BwEeMB4pEEAlFAFUAA+UGrpylIQBOhcuFASfilpKKgA5IQEncWYOE1D6rrC6FB0UCxQqDl5SoNDuExmFEx6kwDUUACMC0PTEAA2gtAtUG3pM108fH0Ni0sjZGNoYiJTM-q5ePtLy6t1u8mAA6YDaACqvGYAGE8KckoU-rg5I8VsA1mQFqiDMZTBYrElukROhw0HRSDsWEjsLiTGZLDIibdmKT0OJSJ0dgAmADMnWpCzp+MZ0iJPP5ZI5UC5fIFNKwwoZhOJvSlIk5EvlCyAAנראה שזה לא חסין לבעיות. הטייפסקריפט מסיק נכון מה הטיפוס של
data
בעת הקריאה לפונקציה, אבל במימוש שלה הוא לא.(כרגע מה שיש לי להציע זה להוסיף המרות בתוך הפונקציה, אבל זה לא יפה).
-
@חגי כתב בטייפסקריפט - טייפ מותנה:
נראה שזה לא חסין לבעיות. הטייפסקריפט מסיק נכון מה הטיפוס של data בעת הקריאה לפונקציה, אבל במימוש שלה הוא לא.
מבחינתי זה לא בעיה כ"כ, כיוון שאני כותב רק קובץ טייפים עבור מי שצורך את הקוד, שמבחינתו הפונקציה היא קופסה שחורה, אבל בתוך הפונקציה אין טייפסקריפט (הערך המוחזר הוא תמיד סטרינג, ההפשטה שלי הייתה מוטעית בזה)
אני בודק אם זה אכן מתאים... -
@חגי @חגי תודה רבה, שילבתי בקוד שלי ועובד מעולה!
אבל משום מה האכיפה היא רק כל עוד חסרים פרופרטי'ס, אבל אם יש התאמה ואני רק מוסיף פרופרטי נוסף שלא מוגדר - אין שגיאה...
דוגמה (בשתי הדוגמאות בסוף אמור להיות שגיאה)עוד משהו שהייתי רוצה לשפר - באחד מהסטים של ה
data
יש פרופרטי אופציונלי של ערך ברירת מחדל, אני רוצה שהערך החזרה של הפונקציה יהיה או סטרינג - או הפרופרטי האופציונלי, אבל במידה ולא הועבר הפרופרטי, או בmode שבו הפרופרטי לא קיים, הערך החזרה יהיה סטרינג קשיח
מצורף דוגמה -
@צדיק-תמים
אופס
https://www.typescriptlang.org/play?#code/C4TwDgpgBAsiAq5oF4oG8CwAoKuoEMATQgLnSgDsBXAWzOpoCMIAnKAXwBps8oqxILMmigBnYELESAlhQDmHbOwDc2AGZUKAY2DSA9hSiE9AZT00IwABay5AHnhQIAD2AQKhUVADWEEHrVYBCQAPgAKGj1CCDJ4TiN8YHwyOERIAG14AF0ASjJxFlsoAB8+Dwg1WQhCdB48AHp6qGlAiKiUVAByIkJOnNqcBqbeLQNxcgYOKFRCRPxVQdxG3igWSyoWQ0mAaigARgXeZfYnABtRaBaoNujprv5BPoGj4bxRinGRAqmZucOhlZrYAbQwFAB0wD0AFUBKwAML4C5hHL-JZNdh1XBAkELDFYbDGMwWay2MLdYideIiNT4XxkPYcFEE0zmSw2eRknqUia0enxGl0qAAJkZCyAA