שימוש בספריות חיצוניות בפרויקט TypeScript

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

1. ספריות הכוללות הגדרות טיפוסים

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

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

דוגמה ראשונה שנראה היא הספריה axios, שעוזרת לנו לשלוח בקשות רשת ב JavaScript ותומכת בדפדפן וב Node.JS. הספריה כתובה ב JavaScript, אבל כוללת קובץ טיפוסים בשם index.d.ts בספריה הראשית שלה.

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

$ npm install --save axios

עכשיו אני נכנס לקוד ב VS Code ופשוט כותב:

axios.

באופן אוטומטי VS Code הוסיף לי את ה import המתאים. בנוסף לחיצה על Ctrl+Space פותחת לי את רשימת ההשלמות ל axios ושם אני יכול לבחור את הפונקציה get:

axios.get(

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

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

$ npx dtsearch axios

ואני מקבל את התוצאות:

   DLS POP NAME               TYPES             DESCRIPTION                                                  DATE       UPDATED
  132m 🔥  axios              <bundled>         Promise based HTTP client for the browser and node.js        2022-09-04 4 days ago
 31.3m 🔥  superagent         @types/superagent elegant & feature rich browser / node HTTP with a fluent API 2022-06-27 2 months ago
 89.6m 🔥  got                <bundled>         Human-friendly and powerful HTTP request library for Node.js 2022-09-02 6 days ago
  4.2m     ky                 <bundled>         Tiny and elegant HTTP client based on the browser Fetch API  2022-09-03 5 days ago
  3.6m     axios-mock-adapter <bundled>         axios adapter that allows to easily mock requests            2022-08-10 a month ago
  2.2m     ky-universal       <bundled>         Use Ky in both Node.js and browsers                          2022-05-07 4 months ago
  2.3m     retry-axios        <bundled>         Retry HTTP requests with axios.                              2022-05-16 4 months ago
474.1k     vue-axios          <bundled>         A small wrapper for integrating axios to Vuejs               2022-06-28 2 months ago
680.4k     xhr-mock           <bundled>         Utility for mocking XMLHttpRequest.                          2022-06-29 2 months ago
190.4k     axios-hooks        <bundled>         axios-hooks                                                  2022-08-31 8 days ago

כל שורה שמוגדרת בתור bundled מייצגת ספריה שכוללת את הגדרות הטיפוסים.

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

2. הגדרות טיפוסים ב DefinitelyTyped

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

$ npx dtsearch lodash

   DLS POP NAME     TYPES           DESCRIPTION
191.1m 🔥  lodash   @types/lodash   lodash modular utilities.

הטקסט @types/lodash אומר שהגדרות הטיפוסים לא נשמרות בתוך החבילה אלא בחבילה אחרת בשם @types/lodash. מאגר בשם Definitely Typed מאגד את כל הגדרות הטיפוסים הקהילתיות כדי שיהיה לנו קל יותר לעבוד עם ספריות JavaScript בתוך פרויקטי TypeScript.

גם אם אתם שוכחים להתקין את ספריית הטיפוסים, ברגע שאתם פותחים את הפרויקט ב VS Code ומנסים לעשות import ל lodash, אז VS Code אוטומטית מנסה לעזור ומציע להתקין עבורכם את @types/lodash.

נשים לב שהגדרת הטיפוסים במצב כזה אינה באחריות כותבי הספריה אלא תרומה מהקהילה. ברוב מוחלט של המקרים הטיפוסים יהיו מעודכנים ומתוחזקים, אבל כן צריך לשים לב יותר שאין טעויות. אפשר למצוא מידע על חבילת הטיפוסים בדף המתאים לה ב npm בקישור: https://www.npmjs.com/package/@types/lodash או במאגר גיטהאב של Definitely Typed בקישור: https://github.com/DefinitelyTyped/DefinitelyTyped.

מבחינת העבודה עם Definitely Typed יש לנו צעד נוסף בהתקנת החבילה. במקום להתקין רק את חבילת lodash אני צריך להתקין גם את חבילת הטיפוסים שלה. נוסיף את שתיהן לפרויקט עם:

$ npm install --save lodash @types/lodash

אחרי ההתקנה הכפולה אני יכול לעבוד עם lodash בדיוק כמו שעבדתי עם axios או moment: אני כותב _. ומקבל אוטומטית את ה import, השלמה עם Ctrl+Space והשלמת פרמטרים והסוגים שלהם אחרי שאני כותב שם של פונקציה.

3. ביטול בדיקת הטיפוסים לספריה מסוימת

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

אני לוקח את lodash בשביל הדוגמה, אבל הפעם אוותר על קובץ הטיפוסים שלה מ Definitely Typed. נפתח פרויקט vite חדש ונתקין רק את lodash:

$ npm install --save lodash

נכנס לקובץ main.js ונוסיף את שורת היבוא:

import _ from 'lodash';

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

Could not find a declaration file for module 'lodash'. '/Users/ynonp/work/courses/typescript/playground/no-types/node_modules/lodash/lodash.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/lodash` if it exists or add a new declaration (.d.ts) file containing `declare module 'lodash';`ts(7016)

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

לכן במקום להתקין את קובץ הטיפוסים מ npm אני יוצר קובץ חדש בשם lodash.d.ts. שם הקובץ הוא חשוב וכן חשוב ליצור אותו בספריה src שמוגדרת בתור תיקיית הקוד הראשית. בתוך הקובץ אני כותב:

declare module 'lodash';

וזה הכל.

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