הטייפים בדרך ל-JavaScript – לא מעט בזכות הישראלים

האם בעקבות ההצלחה של TypeScript הטייפים יגיעו גם ל-JavaScript? יוזמה חדשה שצוברת תאוצה וכבר קיבלה אישור ראשוני שואפת לכך. מתי זה יקרה, מה ההשפעה שתהיה לה על כתיבת קוד JavaScript? ומהי הנקודה הישראלית?

מקור: Unsplash

מאת: גיל תייר

בשנים האחרונות, TypeScript נהפכה לפופולרית ביותר בקרב קהילת ה-JavaScript העולמית. ה-TypeScript נזכיר היא שפה שמרחיבה את JavaScript באמצעות הוספת טייפים (טיפוסים) ובכך מאפשרת למתכנתים לתפוס שגיאות קטנות כמו העברת מספר לפונקציה שמצפה לקבל מחרוזת. הפופולריות של שפת TypeScript הוכיחה שיש רעב בקהילת ה-JavaScript להוספת טייפים לשפה. בעבר היו כמה ניסיונות להכניס טייפים לשפה – ניסיונות שלא צלחו – אבל החדש זה קרה שוב. הוגשה הצעה חדשה להוספת טייפים לשפה. האם הפעם הניסיון להוסיף טייפים יצליח? מה מהות ההצעה להכניס טיפוסים לשפה? איך היא החלה? מה המשמעות שתהיה לה לכתיבת קוד JavaScript? ומה המרכיב הישראלי בהצעה?

המשמעות של הוספת טיפוסים ל-JavaScript

function average(numArray) {
  return numArray.reduce((sum, n) => sum + n, 0) / numArray.length;
}

average([1, 2, 3, 4]) //=> 2.5

מה יקרה אם בטעות נשכח להעביר מערך?

average(1, 2, 3, 4) // Uncaught TypeError: numArray.reduce is not a function

בגלל ש-JavaScript היא שפה דינמית, אנחנו נקבל את השגיאה רק בזמן ריצה; שזה מבאס ומקשה על הפיתוח, אבל היום יש פתרונות לבעיה הזו, בצורה של שפות המרחיבות את JavaScript ומוסיפות להן טיפוסים. הידועה שבהן היא TypeScript, אבל יש אחרות, כמו Flow (של חברת Meta) ו-Hegel.

איך הן עובדות? אנחנו נוסיף אנוטציות (Annotations) בקוד ש-"מסבירות" ל-TypeScript מה הטיפוסים של הפרמטרים, וזה ייראה כך:

function average(numArray: number[]): number {
 return numArray.reduce((sum, n) => sum + n, 0) / numArray.length;
}

average([1, 2, 3, 4]) //=> 2.5
average(1, 2, 3, 4) //=> expected 1 argument, but got 4
בדוגמה הזו אנו מציינים שהפונקציה מקבלת מערך של מספרים ומחזירה מספר

מושלם, נכון? כן. אבל יש רק בעיה אחת: הדפדפן לא מבין את האנוטציות האלה, ויסרב להריץ את הקוד כי זה לא JavaScript חוקי. גם Node.js. לכן שפות כמו TypeScript באות עם קומפיילר (מהדר) שמתרגם את הקוד הנ"ל ל-JavaScript ע"י הורדת ה-type annotations.

וכאן בדיוק טמונה הבעיה, כי סיבכנו את העולם שלנו, שהיה פשוט עד עכשיו. כעת  צריך "לבנות" את הקוד לפני שמריצים אותו. בנוסף לכך, כלים ש"מבינים" קוד צריכים כעת להכיר את הסינטקס של אנוטציות. בעקבות זאת, נוצרו תוספים ל-IDE-ים, ל-Linters, ל-minifiers ול-bundlers – שמבינים את האנוטציות של TypeScript ושל Flow ואחרים.

נשאלת השאלה, האם יש דרך להוסיף את האנוטציות האלו לקוד ללא הסיבוך המתווסף לזה? התשובה אמורה להיות פשוטה. בואו פשוט נוסיף את האנוטציות האלו לשפת JavaScript. אז החודש – אפריל 2022 – זה בדיוק מה שקרה, והצעה בעניין הזה הועלתה ל-TC39, שהיא ועדת התקינה שאחראית על סטנדרטיזציה של JavaScript.

ההצעה להוספת Type Annotations ל-JavaScript

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

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

אז איך מתמודדים עם הבעיה הזו? איך מכניסים type annotations לתוך שפת JavaScript בלי לעשות סטנדרטיזציה לכל הטייפים?

הרעיון הוא פשוט: להוסיף פיצ׳ר לסטנדרט שאומר שצריך להתעלם מ-type annotations בקוד, למשל:

function average(numArray: number[]): number {
 return numArray.reduce((sum, n) => sum + n, 0) / numArray.length;
}

שפת ה-JavaScript תתעלם לגמרי ממה שבא אחרי ה-":". היא תתייחס ל-type annotations כאל הערות (comments). למעשה, השם המקורי של ההצעה הייתה "types as comment". אזורים נוספים שהשפה אמורה "להתעלם מהם" יהיו הדברים שאחרי "type" ו-"interface":

interface Point {
 x: number
 y: number
}

type Circle = {
 center: Point
 radius: number
}

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

אבל שלא תטעו. מה שיש ב-type annotations לא חייב להיות TypeScript. מבחינת JavaScript גם הקוד הבא הוא חוקי:

function average(numArray: THIS!IS!NOT?[TYPESCRIPT]): AT{ALL} {
 // …
}

ההצעה לגמרי מוכנה לקבל איזה type system שתרצו באזורים האלה. ומי יודע? אולי תקום מתחרה רצינית וטובה יותר ל-TypeScript… ההצעה הזו עושה במידה מסוימת דמוקרטיזציה למערכות טייפים. עד כה, כל הכלים נאלצו להכיר את הסינטקס של TypeScript כדי לתמוך בטייפים. כעת, רוב הכלים יוכלו פשוט "לדלג" מעל הטייפים לפי ההגדרה.

ההיסטוריה והנקודה הישראלית

ב-15 לדצמבר 2020, כתבתי בלוג פוסט על JSDoc Typings – דרך להכניס טייפים ל-JavaScript, ע"י שימוש בהערות בקוד. אתם יכולים לקרוא את הפוסט כאן. דניאל אהרנברג, חבר ב-TC39 שכתב לא מעט הצעות לועדה (שגם התקבלו – כדוגמת BigInt), קרא את הפוסט והציע לי להצטרף אליו ולכתוב הצעה שתאפשר להוסיף טייפים לשפה, טייפים שיתעלמו מהם בזמן ריצה. קראנו להצעה "types as comments". הגרסה הראשונה נכתבה תוך כשבועיים.

במהלך שנת 2021 ליטשנו את ההצעה והוספנו אנשים לצוות. במיוחד ראוי לציין את Daniel Rosenwasser, מנהל המוצר של TypeScript ב-Microsoft וגם חבר ב-TC39, שהצטרף כשותף נלהב להצעה. התמיכה של צוות ה-TypeScript הייתה חשובה לנו.

הצגנו את ההצעה בתשיעי למרץ לעולם, וב-31 במרץ 2022 היא הוצגה ל-TC39 שהחליטה לקבל אותה ל-"בחינה".

מקור: Unsplash

וזה טוב לנו?

כשהודענו על ההצעה בטוויטר, האינטרנט פשוט… התפוצץ. לשמחתי, רוב התגובות היו חיוביות, אפילו מתלהבות. חלקן היו… קשות לעיכול (נו, אינטרנט, אתן יודעות..), אבל היו גם תגובות ששאלו שאלות טובות. נציג כאן, באופן חלקי, את השאלות ואת התשובות שלי אליהן.

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

נתחיל באלה שהצרו על הוספת הטייפים לשפה. "JavaScript היא שפה דינמית! איננו רוצים שהיא תהפוך לעוד Java". כתשובה לכך, אציג את הגרף הבא:

בגרף אנו רואים את כמות ה-pull request-ים שקרו בגיטהאב במהלך חודש מרץ השנה. מסתבר שקרוב לחצי מה-pull-request-ים בשפת JavaScript היו בעצם ב-Typescript. כלומר, גם אם את או אתה לא אוהבים טייפים בשפה, הקהילה בוודאי ובוודאי אוהבת אותם.

בניגוד אליהם, יש את הקולות ששואלים "אבל כבר יש TypeScript! למה אנחנו צריכים את זה כחלק מהשפה?". שאלה מצוינת, והתשובה איננה פשוטה. אבל יש לי שלוש תשובות: התשובה הפילוסופית: שפת JavaScript צריכה לחזור לשורשים שלה כשפת scripting פשוטה. כלים כמו typescript מסבכים את החיים כי הם דורשים קומפילציה של קוד. זה מקשה לא רק על המתחילים, אלא גם האנשים שבונים אפליקציות וצריכים להתמודד עם כל הקונפיגורציות (תצורות) השונות. בנוסף, האם המצב שבו אותה קהילה גדולה בעצם מקודדת בשפה אחת (TypeScript) ומריצה שפה אחרת (JavaScript) הגיוני? אנו חייבים לתקן את השסע הזה; התשובה הפרגמטית: לדבג עם source maps הרבה פעמים לא עובד. בנוסף, כל הכלים היום חייבים להבין TypeScript ולעקוב אחרי ההתקדמות של השפה. זה מייצר מונופול: אין היום סיכוי ל-type systems אחרים (כדוגמת Flow) לפרוח וללבלב; והתשובה הפוליטית: ל-TC39, ועדת התקינה של JavaScript, צריכה להיות אחיזה ושליטה במשהו שהוא היום מאוד מאוד פופולרי: הטייפים.

השאלה השלישית וגם הביקורת הנוקבת ביותר היא: "אז בוא נלך עד הסוף עם TypeScript או שאולי נבנה לנו Type system משלנו". התשובה לכך היא ש-Type System זה דבר מאוד מסובך לבנות ולהגדיר. זה ייקח עשור או יותר, עשור שבו TypeScript תמשיך להתקדם ולהתפתח ותייתר את כל העבודה שתעשה בוועדת תקינה.

אז מה זה ייתן לנו?

בעולם שבו ההצעה הזו תהיה חלק מהשפה, נוכל לעשות copy/paste של קוד TypeScript ישר לתוך הקונסול (בדפדפן), והוא פשוט ירוץ. בעולם שבו ההצעה הזו תהיה חלק מהשפה, נוכל לכתוב קוד TypeScript ל-Node.js ופשוט להריץ אותו ללא צורך בקומפילציה מורכבת שמאטה הכל והופכת את הדיבאגינג לאתגר. בעולם שבו ההצעה הזו תהיה חלק מהשפה, כלים כמו Eslint ו-Webpack יוכלו לבדוק גם קוד TypeScript ללא צורך בפלאגינים מיוחדים. עולם כזה יהיה עולם פשוט יותר, מבחינת ההבנה שלנו את הכלים שעוטפים את JavaScript.

ומה עכשיו?

התהליכים ב-TC39 אינם מהירים. הם יכולים לקחת שנים, במיוחד להצעות מורכבות כמו ההצעה הזו. הצעות ב-TC39 עוברות ארבעה שלבים (Stages):

  • שלב 0: צוות מגבש הצעה ראשונית לבחינה בועדה. הועדה עדיין לא קיבלה רשמית את ההצעה.
  • שלב 1: הועדה ראתה את ההצעה ומעוניינת לבחון אותה יותר לעומק. הצוות שעובד על ההצעה צריך לבוא עם הצעה יותר מגובשת ומדויקת.
  • שלב 2: הועדה ראתה את ההצעה המתגבשת ורוצה להמשיך וללטש אותה כדי לסגור את כל הנושאים הפתוחים בהצעה.
  • שלב 3: ההצעה עוברת, והועדה מעוניינת לראות שני יישומים של ההצעה (נניח ב-Chrome וב-Safari) כדי לוודא שהיא עובדת בעולם האמיתי.
  • שלב 4: ההצעה עברה את טבילת האש של העולם האמיתי והועדה מקבלת את ההצעה כחלק משפת JavaScript.

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

הכותב הינו ארכיטקט בכיר בחברת Roundforest

 

 

כתב אורח

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

הגב

14 תגובות על "הטייפים בדרך ל-JavaScript – לא מעט בזכות הישראלים"

avatar
Photo and Image Files
 
 
 
Audio and Video Files
 
 
 
Other File Types
 
 
 

* היי, אנחנו אוהבים תגובות!
תיקונים, תגובות קוטלות וכמובן תגובות מפרגנות - בכיף.
חופש הביטוי הוא ערך עליון, אבל לא נוכל להשלים עם תגובות שכוללות הסתה, הוצאת דיבה, תגובות שכוללות מידע המפר את תנאי השימוש של Geektime, תגובות שחורגות מהטעם הטוב ותגובות שהן בניגוד לדין. תגובות כאלו יימחקו מייד.

סידור לפי:   חדש | ישן | הכי מדורגים
יוני
Guest

כל הכבוד! להגיש הצעה ל-TC39 זו השג מרשים.

אני אישית מתעב את typescript ואת הצורך המלאה להגדיר כל אובייקט כ-type. אחת המשימות המייגעות והמבלבלות ביותר בשפות שהן strongly typed היא המשימה לתת שם לכל מחלקה. בסוף נוצרות מחלקות עם שמות CustomerDetails, CustomerInfo, CustomerExtraInfo וכו׳ וזה מה שקורה ב-typescript היום.

צריך לציין כי מספר framework-ים משתמשים היום ב-typescript (כמו אנגולר) ולכן כל מערכת שמשתמשת ב-framework-ים הללו, בהכרח משתמשת גם ב-typescript וזה מטה את הגרף שהראית

חוץ מזה, כבר היום אפשר להשתמש ב-jsdoc וכל ה-IDE יודעים לייצר autocomplete על בסיסו.

בכל מקרה, בהצלחה

סטארטאפיסט
Guest

בכיין. תשתמש בany אם זה כל כך מפריע לך איפה שצריך.

יואב
Guest

תגובה מגעילה. "בכיין"? היית מדבר ככה לבן אדם שנמצא מולך? לגיטימי לא להסכים, אבל יש צורה.

God Is In The TV
Guest
אין שום יתרון בלהוסיף typeים לJS. JS היא שפה דינאמית ודקלרטיבית מסיבות מוצדקות: * דינאמיות -> JS נועדה לסביבת האינטרנט, שזוהי סביבה דינאמית. אתה שולח בקשה ל API ומקבל מידע דינאמי (בד"כ JSON במבנה כללי כלשהוא.). השפה אינה נועדה לפיתוח בסביבה דטרמיניסטית, כמו הפעלה של לווין. * דקלרטיבית -> הפשטות והנוחות של JS נובעים מכך שהיא דקלרטיבית, כלומר היא יותר מתארת מה הקוד עושה ופחות איך הוא עושה. כלומר: צייר מעגל; ולא: הזז את הסמן 360 מעלות סביב הנקודה, כל נקודה צבע פיקסל בצבע וכו'..; הוספת typeים פוגעת בדקלרטיביות, זוהי תוספת של מידע כיצד לעשות: דקלרטיבי: let cats = document.getById(#catsDiv);… Read more »
איתן
Guest

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

פרי
Guest

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

ASD
Guest

"שגיאות של typeים מתגלות הכי מהר (בהרצה הראשונה) וקלות מאוד לתיקון."

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

מישהו
Guest

מה זה ״סביבה דטרמניסטית״? אתה בא להגיד לי שjs לא דטרמניסטית, זאת טענה די משונה. אם אתה מתכוון לזה שיש הגדרה של שפה ופונקציונליות והסביבה שמריצה אותו אחראית לממש את הפונקציונליות תיארת כל שפת תכנה בערך.
הבעיה שלך עם פגיעה ב״דקלרטיביות״ של js היא היא לא באמת דקלרטיבית, לכן אתה מלכתחילה מוצא את עצמך נאבק בשגיאות כאלה. html ו-css הן דקלרטיביות ושם באמת גם *לא צריך* טייפים.

ג׳ו
Guest

במקרה של typescript ל JavaScript תהליך ה build נקרא transpile ולא compile.
בתהליך העברת קוד מקור בשפה אחת לקוד מקור בשפה אחרת

חכלכלכח
Guest

תודה לך, סוף סוף נוכל להפתר מגוש הבאגים שהוא הקומפיילר של מייקרוסופט

בר.
Guest
שמע, אני לא מבין איזה use case זה בא לפתור. יופי, אז עכשיו כל מה שאחרי הנקודותיים יהיה comment. אבל מה זה נותן? הרי זה לא יאפשר להוסיף טייפים בלי interpreter של TS. כאילו, זה בגדול נותן שאם מסיבה לא ברורה הTSC לא רץ אז הדף עוד עלול איכשהו להתקמפל. נו ו… מי יכול לרצות דבר כזה? אם TS לא תירגם לי לjs אין לי שום סיבה בעולם שאני ארצה שהקוד "יתקמפל", כי כאמור יש לי שלב בתהליך שמשום מה לא רץ. אבל מלבד זאת, מה שבאמת מעצבן אותי זה שהכותרת כל כך מטעה ולא נכונה שהיא גורמת לי לרצות… Read more »
מישהו
Guest

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

כיוקמכ
Guest

130% מטומטם.

יוסי
Guest

אותי משגע מבחינת ניהול זיכרון וקומפילציה, למה לא להגדיר type?
זה יוכל לשפר משמעותית ביצועים במערכות מורכבות

wpDiscuz

תגיות לכתבה: