TypeScript הוא JavaScript עם מערכת טיפוסים סטטית שנוספה מעליו. כל תוכנית JavaScript היא תחביר TypeScript תקין; TypeScript מוסיף הערות טיפוס, קומפיילר שבודק אותן לפני שהקוד רץ, ושלב build שמסיר אותן שוב. בזמן ריצה יש רק JavaScript, כך שההבדל כולו הוא במה שמגלים לפני שמשחררים את הקוד.
ב-JavaScript אותה פונקציה היא הקוד הזה בלי type Product = ..., : Product[] ו-: number. הטיפוסים מוסיפים מידע לקומפיילר ולעורך; הם לא משנים את מה שהתוכנית עושה.
TypeScript מול JavaScript במבט אחד
| JavaScript | TypeScript | |
|---|---|---|
| מערכת טיפוסים | דינמית: טיפוסים שייכים לערכים וידועים רק בזמן ריצה | סטטית: טיפוסים מוצהרים או מוסקים ונבדקים בזמן קומפילציה |
| מתי שגיאות טיפוס מתגלות | כשהשורה רצה (undefined, NaN, TypeError) | בעורך תוך כדי הקלדה, ובזמן קומפילציה |
| איפה הוא רץ | דפדפנים, Node.js, Deno, Bun, ישירות | באותם מקומות, אחרי שהטיפוסים מוסרים |
| שלב build | לא נדרש | tsc או bundler, או סביבת ריצה שמסירה טיפוסים בעצמה |
| קבצים | .js, .mjs, .cjs | .ts, .mts, .cts, .tsx, ובנוסף הצהרות טיפוסים ב-.d.ts |
| מהירות בזמן ריצה | נקודת הייחוס | זהה: הפלט הוא JavaScript |
| תמיכה בעורך | השלמה אוטומטית מטיפוסים מוסקים ומ-typings של ספריות, שעלולים להיות חלקיים | השלמה אוטומטית, שינוי שם ו-"find all references" מטיפוסים מוצהרים |
| עקומת למידה | נמוכה יותר | JavaScript ועוד מערכת הטיפוסים |
| תקן | ECMAScript, על ידי TC39 | פרויקט קוד פתוח של Microsoft שעוקב אחרי ECMAScript |
אותו קוד בשתי השפות
הנה פונקציה ב-JavaScript. שום דבר בה לא אומר איך user צריך להיראות:
function greeting(user) {
return `Hello, ${user.firstName} ${user.lastName}`;
}
greeting({ firstname: "Ada", lastName: "Lovelace" });
// "Hello, undefined Lovelace", no error anywhere
גרסת ה-TypeScript מצהירה על המבנה פעם אחת, ושגיאת ההקלדה מדווחת לפני שהקוד רץ:
interface User {
firstName: string;
lastName: string;
}
function greeting(user: User): string {
return `Hello, ${user.firstName} ${user.lastName}`;
}
greeting({ firstname: "Ada", lastName: "Lovelace" });
// error TS2561: Object literal may only specify known properties,
// but 'firstname' does not exist in type 'User'. Did you mean to write 'firstName'?
הערות הטיפוס הן כל ההבדל בתחביר. TypeScript מוסיף גם כמה הצהרות משלו (interface, type, enum, generics כמו Array<string>, מגדירי גישה כמו private), אבל הפקודות, האופרטורים והאובייקטים המובנים הם של JavaScript.
מה TypeScript תופס ש-JavaScript לא
JavaScript ממיר טיפוסים בשקט. הבאג הזה נפוץ עם ערכים שמגיעים משדות של טפסים, שתמיד הם מחרוזות. הריצו כדי לראות מה הקומפיילר אומר:
index.ts(7,17): error TS2345: Argument of type 'string[]' is not assignable to parameter of type 'number[]'.
Type 'string' is not assignable to type 'number'.
ב-JavaScript הקוד רץ ומדפיס 010205, כי 0 + "10" הוא שרשור מחרוזות. TypeScript מסרב לקמפל עד שהמחרוזות מומרות, למשל עם fromForm.map(Number).
הקטגוריה הגדולה השנייה היא ערכים שאולי חסרים. Array.prototype.find מחזיר undefined כששום דבר לא מתאים, ו-TypeScript מחייב אתכם לטפל בזה:
index.ts(8,13): error TS18048: 'user' is possibly 'undefined'.
גרסת ה-JavaScript הרגילה קורסת בזמן ריצה עם TypeError: Cannot read properties of undefined (reading 'name'). התיקון ב-TypeScript הוא לטפל במקרה שהקומפיילר הצביע עליו:
פלט:
GRACE
no user with id 3
מה ש-TypeScript לא תופס: שגיאות לוגיות (לנוסחה שגויה יש את הטיפוס הנכון), וכל דבר שקשור לנתונים שנכנסים לתוכנית בזמן ריצה. תגובה מ-API שמוגדרת כ-User נכונה רק במידה שהשרת ששלח אותה נכון, כי הטיפוסים נעלמים ברגע שהקוד רץ. בדקו נתונים כאלה בקוד של זמן ריצה.
שימוש בספריות JavaScript ב-TypeScript
כל חבילת npm עובדת מ-TypeScript, כי הפלט הוא JavaScript בכל מקרה. הטיפוסים של חבילה מגיעים מאחד משלושה מקומות:
- החבילה כוללת קובצי
.d.tsמשלה. רוב החבילות שמתוחזקות באופן פעיל כוללות, ולא צריך להתקין שום דבר נוסף. - חבילת
@typesנפרדת מהפרויקט הקהילתי DefinitelyTyped:npm install --save-dev @types/lodashמוסיף טיפוסים ל-lodash. - משום מקום. במקרה כזה, כש-
strictמופעל, ה-import עצמו הוא שגיאה:
error TS7016: Could not find a declaration file for module 'lodash'. '/project/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';`
התיקון הוא להתקין את חבילת ה-@types אם היא קיימת, או לתאר את המודול בעצמכם בקובץ .d.ts; עמוד קובצי ההצהרה מראה איך.
שלב ה-build
דפדפנים ו-Node.js לא בודקים טיפוסים, ולכן TypeScript צריך שלב בין קוד המקור שלכם לקוד שרץ. יש שלושה מבנים נפוצים:
tscמקמפל הכול. הוא בודק טיפוסים וכותב קובצי.js, בדרך כלל לתיקייתdist. פשוט, והסטנדרט לספריות.- bundler או dev server מסירים את הטיפוסים, ו-
tsc --noEmitבודק אותם. Vite ו-esbuild מסירים טיפוסים בלי לבדוק, וזה שומר על טעינות מחדש מהירות; העורך ושלב ב-CI מריצים את בודק הטיפוסים. - סביבת הריצה מסירה את הטיפוסים. גרסאות עדכניות של Node.js, Deno ו-Bun מריצות קובצי
.tsישירות. אף אחת מהן לא בודקת טיפוסים בזמן ההרצה, ולכןtsc --noEmit(אוdeno check) הוא עדיין הדרך למצוא שגיאות טיפוס.
JavaScript לא צריך שום דבר מזה, וזה היתרון המעשי הגדול ביותר שלו בסקריפטים קטנים. העלות של שלב ה-TypeScript היא בעיקר הגדרה, tsconfig.json ותלות פיתוח ב-typescript, וזמן קומפילציה; הקומפיילר ה-native של TypeScript 7 קיצר את הזמן הזה בערך פי עשרה בפרויקטים גדולים.
עקומת הלמידה
כל מה שאתם יודעים על JavaScript עובר איתכם, כי זמן הריצה של TypeScript הוא JavaScript. החומר החדש הוא מערכת הטיפוסים, והוא מגיע בשכבות:
- הערות טיפוס על משתנים, פרמטרים וערכי החזרה (
: string,: number[]). - טיפוסי אובייקטים עם
interfaceו-type, מאפיינים אופציונליים, unions כמוstring | number. - Narrowing: בדיקת ערך עם
typeof,inאו===כדי שהקומפיילר יידע באיזה מקרה אתם נמצאים. - Generics, טיפוסי עזר כמו
Partial<T>ו-Pick<T, K>, וטיפוסים מתקדמים לכותבי ספריות.
שתי השכבות הראשונות מכסות את רוב הקוד של אפליקציות. חלק גדול מהטיפוסים מוסק, ולכן הרבה קוד TypeScript נראה כמו JavaScript עם הערות טיפוס רק בחתימות של פונקציות.
מתי לבחור ב-TypeScript ומתי ב-JavaScript
האם TypeScript עדיף על JavaScript? לקוד שכמה אנשים מתחזקים או שחי שנים, בדרך כלל כן, והתעשייה זזה בכיוון הזה: לפי הספירה של GitHub של תורמים חודשיים, TypeScript עקף גם את JavaScript וגם את Python באוגוסט 2025 והפך לשפה הנפוצה ביותר ב-GitHub. לסקריפטים קטנים, JavaScript רגיל הוא לעיתים קרובות הכלי הטוב יותר.
בחרו ב-TypeScript כש:
- יותר מאדם אחד עובד על הקוד, או שהוא יתוחזק חודשים או שנים.
- בסיס הקוד גדול מספיק כדי שאי אפשר לזכור כל חתימה של פונקציה.
- אתם עושים refactoring לעיתים קרובות: שינוי שם של מאפיין מעדכן כל שימוש, והקומפיילר מפרט כל מה שנשאר.
- אתם מפרסמים ספרייה: קובצי ה-
.d.tsנותנים למשתמשים שלה השלמה אוטומטית ובדיקות. - ה-framework מצפה לזה. אפליקציות Angular נכתבות ב-TypeScript, Next.js ו-Astro יוצרים פרויקטים חדשים ב-TypeScript כברירת מחדל, ולתבניות React, Vue ו-Svelte של Vite יש לכל אחת גרסת TypeScript.
בחרו ב-JavaScript כש:
- התוכנית היא סקריפט קצר, ניסוי חד-פעמי או קטע קוד בקונסולה של הדפדפן.
- אתם לומדים תכנות בפעם הראשונה ורוצים פחות מושגים בבת אחת.
- אין שלב build ואתם לא רוצים אחד. גם אז,
// @ts-checkעם JSDoc נותן בדיקה מסוימת בקובץ.jsרגיל.
העברת פרויקט JavaScript ל-TypeScript
ההעברה לא חייבת לקרות בבת אחת. הקומפיילר מקבל JavaScript לצד TypeScript:
{
"compilerOptions": {
"allowJs": true,
"checkJs": false,
"outDir": "dist",
"rootDir": "src"
},
"include": ["src"]
}
עם allowJs, קובצי .js מתקמפלים ויכולים לייבא מקובצי .ts וגם להפך. אחר כך המירו בהדרגה:
- שנו שם של קובץ אחד מ-
.jsל-.tsותקנו את השגיאות שהקומפיילר מדווח עליהן בו. - התחילו מהעלים (מודולי עזר עם מעט imports), ואז התקדמו פנימה.
- הפעילו את
checkJs, או הוסיפו// @ts-checkבראש קובצי.jsבודדים, כדי לבדוק טיפוסים בקבצים שעוד לא שיניתם את שמם.
בקובצי JavaScript שנבדקים, הערות JSDoc מספקות את הטיפוסים:
// @ts-check
/**
* @param {number} price
* @param {number} qty
* @returns {number}
*/
function lineTotal(price, qty) {
return price * qty;
}
lineTotal("3", 2);
// error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
יש צוותים שעוצרים כאן: קובצי JavaScript עם טיפוסי JSDoc, שנבדקים על ידי tsc, בלי שלב build לקוד עצמו. אחרים מגיעים עד הסוף ל-.ts. אם מפעילים strict בפרויקט קיים, צפו להרבה שגיאות בהתחלה; עמוד ה-strict mode מפרט מה כל דגל בודק, כך שאפשר להפעיל אותם אחד אחרי השני.
שאלות נפוצות
מה ההבדל העיקרי בין TypeScript ל-JavaScript?
TypeScript מוסיף טיפוסים סטטיים ל-JavaScript. מתארים מה כל ערך הוא (name: string, items: Item[]), והקומפיילר של TypeScript מדווח על טעויות לפני שהקוד רץ. JavaScript לא בודק כלום מראש: טיפוס שגוי מתגלה רק כשהשורה מתבצעת, לרוב כ-undefined או כ-TypeError.
האם TypeScript עדיף על JavaScript?
ברוב הפרויקטים שיותר מאדם אחד מתחזק, או שחיים יותר מכמה שבועות, כן: טיפוסים תופסים קטגוריות שלמות של באגים, הופכים refactoring לבטוח ומזינים את ההשלמה האוטומטית של העורך. לסקריפט קצר, לאב טיפוס מהיר או לתרגיל למידה, JavaScript רגיל מהיר יותר להתחלה ולא צריך הגדרת build.
האם TypeScript מהיר יותר מ-JavaScript?
לא, וגם לא איטי יותר. TypeScript מתקמפל ל-JavaScript והטיפוסים נמחקים, כך שהקוד שרץ הוא אותו JavaScript שהייתם כותבים ידנית. העלות הנוספת היחידה היא זמן הקומפילציה בזמן הפיתוח.
כדאי ללמוד קודם JavaScript או TypeScript?
למדו את יסודות JavaScript קודם, או יחד עם TypeScript. כל ההתנהגות בזמן ריצה (משתנים, פונקציות, אובייקטים, מערכים, promises) היא JavaScript, ו-TypeScript רק מתאר אותה. ברגע שאתם יודעים לכתוב תוכניות JavaScript קטנות, הוספת טיפוסים היא צעד קצר.
אפשר להשתמש ב-TypeScript וב-JavaScript באותו פרויקט?
כן. הגדירו "allowJs": true ב-tsconfig.json והקומפיילר יקבל קובצי .js לצד קובצי .ts. הוסיפו "checkJs": true (או הערת // @ts-check בכל קובץ) כדי לבדוק טיפוסים גם בקובצי ה-JavaScript, עם טיפוסים מהערות JSDoc. זו הדרך המקובלת להעביר פרויקט קובץ אחר קובץ.