MasterScripter

המדריך השלם ל – TypeScript

תוכן עניינים

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

לאלה מכם שלא רוצים לקרוא את החפירות על התהוות השפה, איפה נולדה ובאיזה משקל (ממליץ שכן!), מוזמנים לקפוץ היישר לתחילת המדריך

נצא לדרך 🙂

TypeScript- תעודת זהות

Typescript (בקיצור: TS) הינה שפת תכנות חינמית ובקוד פתוח, שפותחה במשך כשנתיים ע"י מיקרוסופט וראתה אור לראשונה בשנת 2012.
היא מאוחסנת ב – Github ומטרתה להתמודד עם חסרונות קיימים ב – Javascript ע"י הוספת סוגים, מחלקות, מודולים ועוד.
חשוב להבין ש – TypeScript הינה הרחבה ל – Javascript והיא מכילה את כל הפקודות והתחביר של שפת המקור. רוצה לומר: ניתן לשלב JS בתוך TS.
בסופו של דבר קוד Typescript מעובד לכדי קוד JavaScript ולכן ניתן לומר "באחריות" שהשפה נתמכת בכל דפדפן שתומך ב – JavaScript.
קבצי TypeScript יישמרו בסיומת ts או tsx.

TypeScript – למה?

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

החסרון העיקרי של Javascript הוא – השפה לא מותאמת לשימוש בה כיום.
במקור, JS הוטמעה כשפת תסריט עבור HTML, או "שפת תכנות עבור HTML", ולכן פותחה כשפה דינאמית מתוך מטרה שתהיה "קלה" ככל האפשר: סוג המשתנה נקבע אוטומטית, וניתן לשינוי בכל רגע נתון.
כך לדוגמה, נוכל להגדיר משתנה מסוג מספר שלם (Integer):

ולשנות אותו למשתנה מסוג בוליאני (או לכל סוג אחר של משתנה):

במהלך השנים, השימוש ב – JS גדל, השפה הפכה לדינמית יותר עם הטמעת AJAX ובתקופה הזו אנחנו חווים עלייה מתמדת במגוון הדרכים בהן ניתן להשתמש ב – Javascript, מאז שHTML5 הוטמע באופן סופי בשנת 2014.

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

Ecma International, הארגון שאחראי על הסטנדרט של שפת Javascript, התחילו להפנים את השינויים שהתרחשו בעולם האינטרנט בכלל ובשימוש ב – JS בפרט, ובשנה שעברה (2015) יצא הסטנדרט החדש, שנקרא ES6 או ECMASCRIPT 2015, שכולל מרכיבים רבים שקיימים בדרך כלל בשפות תכנות: קבועים, מחלקות, מודולים ועוד.

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

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

המטרות שבשמן פותחה השפה

את כלל המטרות העיצוביות של השפה ניתן לקרוא (באנגלית) בדף ה – Github של שפת התכנות.

בחרתי לפרט על 3 מטרות שאני רואה בהן מטרות "ראשיות":

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

המהדר של TypeScript בודק סוגי משתנים/מחלקות/… כבר בשלב הקומפילציה מתוך מטרה לאתר שגיאות אפשריות.

ניקח לדוגמה, את הקוד הבא, שכתוב ב – JS:

האופרטור === בודק האם שני המשתנים זהים גם בתוכנם וגם בסוגם.
השוואה שכזו איננה נכונה לוגית, מכיוון שהמשתנה a הוא מסוג מחרוזת (string), בעוד המשתנה b הוא מסוג מספר שלם (integer).

כאשר נכתוב את אותו קטע קוד ב – TypeScript, מיד תקפוץ שגיאה שתודיע לנו שלא ניתן להשתמש באופרטור '===' עבור סוגי המשתנים הללו:

"Operator '===' cannot be applied to types 'string' and 'number'"

ב – JS לעומת זאת, הפקודה תתבצע ותחזיר FALSE.

לספק מנגנון לכתיבת קוד מסודר

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

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

להוות כלי פיתוח חוצה פלטפורמות

מיקרוסופט שחררה את השפה תחת רישיון קוד פתוח (Open Source Apache License) והיא ניתנת להתקנה בכל מערכת הפעלה.
מדובר במהלך לא אופייני למיקרוסופט, שבדרך כלל מפתחת בקוד סגור. התוצאות לא מאחרות לבוא: בדיקה ב – Google Trends לגבי מידת העניין ב – TypeScript לעומת המתחרות CoffeScript ו – Dart מראה את העלייה המטאורית של השפה מחודש יציאה באוקטובר 2012 ועד היום, בכל העולם.

מהתרשים אפשר ללמוד על הנסיקה של שפת התכנות, במיוחד בשנת 2016.
הסיבה העיקרית, ככל הנראה, לעלייה בפופולאריות של השפה היא אימוצה על-ידי צוות הפיתוח של Angular2, כפי שכתב שלומקה בפוסט המלחמתי-משהו: השוואה בין Angularjs 2 ל – ReactJS.

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

איך זה עובד?

מבלי להיכנס לנבכי המהדר של TypeScript, אסביר בקצרה את העקרון שעומד מאחורי השפה.
כתבתי זאת מס' פעמים במהלך הפוסט – TypeScript היא מעין שפת "מעבר". בסופו של דבר, כל קוד שנכתוב בקובץ ts יומר לקוד js ע"י המהדר.
הקובץ שנייבא למסמך ה – HTML שלנו יהיה קובץ JS, ולא קובץ TS.

לדוגמה, הקוד הבא:

יומר לקוד Javascript רגיל ובלתי תלוי:

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

ועכשיו לדבר האמיתי: המדריך השלם ל – TypeScript – חלק א.

התקנה

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

Nods.js

ניתן להתקין את המהדר כחבילה ל – Nods.js, ולהריצו באמצעות שורת הפקודה (CLI).
בשביל להתקין, נריץ את הפקודה הבאה:

npm install -g typescript

בשביל לבצע הידור לקובץ ts, נריץ את הפקודה הבאה:

tsc filename.ts

מי שמחפש אמצעי קליל יותר לצורכי לימוד ימצא פתרון במגרש המשחקים באתר הרשמי של TypeScript, שמציג את ההמרה ל – JavaScript ומאפשר להריץ את הקוד.

עורכי טקסט (סביבות פיתוח)

עורכים רבים מכילים יישום של המהדר, ומקמפלים את הקוד אוטומטית בעת השמירה:

  • Visual Studio 2013 / 2015 / Code
  • Sublime Text
  • Atom
  • Eclipse
  • Emacs
  • WebStorm
  • Vim

(הרשימה נלקחה מהאתר של TypeScript, ככל הנראה ישנם עורכים נוספים שמכילים את המהדר)

tsconfig.json – קובץ הגדרות המהדר

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

Typescript: Create Tsconfig.json Project File

שתיצור אוטומטית את קובץ ההגדרות.
ובכל זאת, נתעכב (בקטנה) על מבנה קובץ ההגדרות.

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

במצב הזה, המהדר ישאב את הגדרות ברירת המחדל שלו, וכל קובץ .ts בכלל התיקיות בפרוייקט יעבור הידור ויתורגם ל – JS.

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

compilerOptions (אובייקט)

אם נרצה להעביר למהדר הגדרות מותאמות אישית, נעשה זאת באמצעות התכונה compilerOptions.
דוגמה:

פירוט מלא של ההגדרות הזמינות (באנגלית) ניתן למצוא כאן

files (מערך)

התכונה מאפשרת להגדיר קבצים שיעברו קומפילציה

exclude (מערך)

התכונה מאפשרת לפרט תיקיות/קבצים שלא יעברו קומפילציה

* לא ניתן להשתמש ב – files וב – exclude יחדיו. כאשר שניהם קיבלו ערך, התכונה files תקבל עדיפות על פני exclude.

compileOnSave

כאשר מוגדרת כ – true, מסמנת לעורך הטקסט לבצע קומפילציה בכל פעם שהקובץ נשמר.
נכון להיום, התכונה נתמכת רק ב – Visual Studio 2015 ובפלאגין atom-typescript לעורך הטקטס Atom.

סוגי נתונים

TypeScript מציעה סוגי נתונים רבים.
בניגוד ל – JS ובדומה לשפות כמו JAVA ו – C, לא ניתן לשנות את סוג המבנה מרגע שהוגדר כלומר – לא ניתן לשנות את סוג הערך.

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

Boolean (בוליאני)

סוג נתונים שיכול לקבל שני ערכים: true או false.
בניגוד לשפות מסויימות (לדוגמה: PHP), לא ניתן להשתמש ב – 1 או 0 כתחליפים.

Number (מספר)

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

String (מחרוזת)

בניגוד לשפות כדוגמת Java ובדומה ל – PHP, לא קיים הבדל בין גרשיים כפולים ( " ) או גרש אחד ( ' ).
כלומר, אין סוג נתונים character (תו).

תכונה קטנה אך משמעותית היא היכולת להשתמש במשתנים בתוך המחרוזת, בלי הצורך להשתמש באופרטור +.

Javascript:

TypeScript:

שימו לב לשימוש בתו ` (גרש נטוי). אם נשתמש בגרש יחיד או בגרש כפול, המהדר יפרש זאת כמחרוזת רגילה.
המהדר יודע לזהות ירידת שורה ולכן אין צורך להשתמש בתווים כמו \n.

Array (מערך)

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

ניתן להכריז על מערך בשתי דרכים:

או:

Tuple (‏n-יה סדורה)

n-יה סדורה, או בשמה העברי הלא רשמי – רשימה,  הינה מערך שבו אנו מגבילים מראש את סוגי האיברים שהמערך יוכל להכיל.

יש לשים לב שסדר השמת הסוגים משמעותי:

בניגוד לשפות אחרות כמו Python שבהן לא ניתן לעדכן את הרשימה לאחר הגדרתה, ב – TypeScript ניתן להוסיף איברים נוספים, כל עוד הם נכללים ברשימת הסוגים שהוגדרו:

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

Enum (רשימת בחירה)

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

TypeScript מאפשרת למפתח לקבוע בעצמו את הערך שיקבל כל איבר:

אפשרות נחמדה נוספת היא לקבל את שם האיבר לפי הערך המספרי שלו:

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

Any (סוג לא ידוע)

סוג נתונים שמאפשר "לבטל" את קביעת סוג הנתונים הסטטית של המהדר.
מאפשר לעבוד עם ספריות JS קיימות ו/או עם קלט מסוג לא ידוע (קלט ממשתמש, קלט מספריית צד שלישי).

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

סוג הנתונים any מאפשר ליצור מערך עם סוגי נתונים שונים:

Void (חסר סוג נתונים)

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

הצמדת סוג נתונים (type assertion)

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

הדוגמה הבאה ממחישה מצב שכזה:

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

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

var p: Principle = t; // Type 'Teacher' is not assignable to type 'Principle'

זאת מכיוון שהמהדר זיהה ניסיון ליישם ערך מסוג Teacher למשתנה מסוג Principle.
עם זאת, אנו יודעים להגיד שמדובר בפקודה תקינה ולכן, כדי לעקוף את המהדר, נצמיד למשתנה t את סוג הנתונים Principle, באמצעות הפקודה as:

הצמדת סוג נתונים תתאפשר רק כאשר סוג הנתונים <p> הוא תת-סוג של <t> או להפך.
כלומר, בדוגמה למעלה, הצמדת סוג נתונים מתאפשרת רק מכיוון ש – Principle מרחיב את Teacher.

הצמדת סוג נתונים כפולה

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

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

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

הכרזה על משתנים

TypeScript מיישרת קו עם ECMAScript 2015, וכוללת שתי דרכים חדשות להכריז על משתנה:

let

מבחינת תחביר, הכרזה על משתנה באמצעות let זהה ל – var:

ההבדל טמון בסמנטיקה: משתנה שהוגדר עם המילה let יתקיים אך ורק בתוך המרחב (scope) של מבנה הנתונים בו הוא נמצא.

אם היינו משתמשים ב – var במקום ב – let, ערכו של המשתנה x בסוף הריצה (10) היה נשמר גם לאחר סיום ריצת הלולאה.

const

אשפי תכנות מונחה עצמים – אל תקפצו לפסקה הבאה!
למרות השם (המעט מטעה), קבוע ב – TypeScript שונה מקבועים בשפות תכנות רבות. בערך:

בדומה לעקרון בכל שפת תכנות, כאשר ניישם ערך לקבוע, לא ניתן יהיה לשנות את הערך ואת המבנה שלו:

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

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

פונקציות

TypeScript מציגה לראווה מס' שיפורים ליכולות הקיימות של פונקציות ב – JavaScript.

כתיבת פונקציה זהה בבסיסה לכתיבה הרגילה של Javascript:

אבל באנו לרשום TypeScript ולא JavaScript, אז בואו ננצל את יכולותיה של השפה ונצמיד לפונקציה ולפרמטרים סוג נתונים:

פרמטרים אופציונליים

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

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

ערך ברירת מחדל

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

ב – TypeScript, לעומת זאת, קל לתת ערך ברירת מחדל:

קלי קלות!

פרמטר מאגד

אחת האפשרויות המגניבות (לדעתי) ב – TypeScript, שקיימת אגב גם ב – ES6 (בא להגיד: בעתיד תוכלו להשתמש בה ב – VanillaJS), היא פרמטר מאגד (באנגלית: Rest Parameter) –
פרמטר שחייב להיות מערך, ואיבריו הם שארית הפרמטרים שסופקו לפונקציה, לא כולל פרמטרים שהוגדרו לפני הגדרת הפרמטר המאגד.
נכריז על פרמטר כפרמטר מאגד ע"י הוספת 3 נקודות () לפני תחילת שמו.
ההסבר אולי מסובך, אבל הדוגמה הופכת הכל לברור:

בדוגמה, הפרמטר הראשון – firstname קיבל את הערך הראשון שהועבר, והפרמטר השני – restOfName קיבל לתוכו את כל שאר השמות.

(כותב הפוסט לא מכחיש את תמיכתו בתביעתה של דאינריז לכס הברזל)

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

העמסה

אין ספק שבשפה כל כך דינאמית כמו JavaScript, עקרון העמסה הוא חשוב מאין כמוהו.
TypeScript מספקת טכניקת העמסה פשוטה ומוכרת, שמיושמת בשפות כמו JAVA ו – SWIFT.

אם ב – JavaScript אנחנו נאלצים לנתח את הפרמטר בגוף הפונקציה:

ב – TypeScript, העבודה תיעשה בשבילנו:

וכשלוקחים בחשבון את היכולת ליצור סוגי-נתונים מותאמים אישית, העמסה הופכת ליכולת משמעותית יותר ש – TypeScript נותנת לנו המפתחים.

וזה בדיוק העיתוי המושלם להתעמק בסוגי נתונים מותאמים אישית, או בשמם הרשמי:

מחלקות

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

מבחינה תחבירית, מחלקות נכתבות באופן דומה ל – JAVE ו – C#.

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

  • הכרזה על המחלקה
  • תכונות מחלקה
  • פונקציית בנאי
  • פונקציות מחלקה
  • גישה לתכונות המחלקה באמצעות המילה השמורה this

לוואים

public

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

אבל גם באספקט הזה TypeScript לא נשארת מאחור ומכילה גם את private וגם את protected לצד readonly המוכר למתכנתי C#.

protected

תכונות המחלקה שיזכו למקדם protected יהיו נגישות אך ורק מתוך המחלקה ומתוך מחלקה מרחיבה, אך לא מחוץ למחלקה:

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

Property 'type' is protected and only accessible within class 'Input' and its subclasses

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

השגיאה שמתקבלת תודיע לנו שפונקציית הבנאי לא נגישה מחוץ למחלקה:

Constructor of class 'Input' is protected and only accessible within the class declaration

למרות זאת, המחלקה כן ניתנת להרחבה.

private

גם כאן, private פועל כמצופה ואוטם הרמטית כל גישה לתכונה מחוץ למחלקת האם:

מכיוון שנעשה ניסיון לגשת למשתנה המחלקה dirty, שהוא private, נקבל את השגיאה הבאה:

Property 'dirty' is private and only accessible within class 'Input'

כמובן שגם ניסיון לגשת למשתנה מחוץ לכל מחלקה, יניב אותה שגיאה.

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

readonly

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

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

ממשקים

נגדיר ממשק באמצעות המילה השמורה interface:

נשתמש בהצמדת נתונים בשביל לשייך את הממשק:

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

נקבל שגיאה:

Argument of type '{ title: string; content: string; attachments: {}; }' is not assignable to parameter of type 'Message'

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

אבל איך בכל זאת נתמודד עם תכונות כמו מכותבים, שלעתים ייעשה בהן שימוש ולפעמים לא? יש לי תחושה שאתם כבר יודעים את התשובה..

תכונות אופציונליות

תיאור תכונה בממשק כתכונה אופציונלית תיעשה באמצעות הוספת סימן שאלה (?) בסוף השם של התכונה:

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

תכונות לקריאה בלבד

אנחנו מכירים את הלוואי readonly מהמחלקות, וגם בממשקים הוא לא נוטש אותנו:

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

תיאור פונקציות

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

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

יישום הפונקציה ייראה כך:

יישום ממשק במחלקה

נכריז על יישום ממשק במחלקה באמצעות המילה השמורה implements:

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

Class 'User' incorrectly implements interface 'UserStructure'

הרחבת ממשק

ניתן להרחיב ממשק בדומה לדרך שבה מרחיבים מחלקה – באמצעות המילה השמורה extends:

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

ממשק מרחיב מחלקה

TypeScript מאפשרת לממשק להרחיב מחלקה ובעצם לרשת את תכונותיה והפונקציות שלה, גם כן באמצעות המילה השמורה extends:

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

מה, כבר נגמר?

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

מקווה שלמדתם והשכלתם, קדימה לחלק ב'!

מקורות

  1. בסיס למדריך וקטעי קוד

אם הגעת עד לפה, הגיע הזמן להירשם לניוזלטר!

Summary
Article Name
המדריך השלם ל - TypeScript: חלק א'
Description
חלק א' של מדריך מקיף הכולל הסבר על שפת התכנות TypeScript או בשמה המקוצר: TS.
Author
Publisher Name
MasterScripter
Publisher Logo
אודות 
hello world! אני יונתן, מתעסק בתכנות ופיתוח WEB פלוס מינוס מאז שאני זוכר את עצמי. ב2013 הקמתי את קבוצת סיזן ביחד השותף היקר שלי - שלומי שלומקה זק. ביום מתעסק בפיתוח ועיצוב אתרי אינטרנט ואפליקציות, עיצוב חוויית משתמש, הקמת מיזמים, ועוד..אבל מה שלא ידעתם עליי - זה שבלילה אני באטמן. אל תגלו לאף אחד!

9 תגובות

  1. david

    28 בנובמבר 2016 - 16:02
    תגובה

    מושלם!
    תודה רבה!
    מחכים לחלק ב':)

      • מתכנתת

        29 בנובמבר 2016 - 7:44
        תגובה

        נשמח למאמר גם על flow

          • מתכנתת

            30 בנובמבר 2016 - 11:03

            מתי הוא יהיה מוכן בערך? המאמרים שלך מצויינים!

          • יונתן נקסון

            30 בנובמבר 2016 - 17:37

            יש עוד כמה מאמרים בקנה שאנחנו עובדים עליהם, אבל אני בהחלט מוצא לנכון לבצע השוואה בין FLOW ל – TYPESCRIPT.
            אם יש דברים ספציפיים שהיית רוצה שאתייחס אליהם, אני אשמח אם תשלחי לנו למייל – helloworld@masterscripter.co.il

            ואני מבטיח להתייחס לכך בפוסט!

            תודה על המחמאה, כיף לשמוע 🙂

  2. אסף

    28 בנובמבר 2016 - 22:57
    תגובה

    אלוף, כל הכבוד

  3. חיים

    8 במאי 2017 - 0:23
    תגובה

    חסר על promise ו observebale
    תותח

השאר/י תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *