5.1 הקדמה לטייפסקריפט פתרון
פתרון - הקדמה לטייפסקריפט¶
פתרון תרגיל 1¶
א. הקמת הפרויקט:
ב. קובץ tsconfig.json:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"strict": true,
"outDir": "dist",
"rootDir": "src",
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
},
"include": ["src/**/*"]
}
ג. קובץ src/index.ts:
ד. קומפילציה והרצה:
פתרון תרגיל 2¶
הוספת type annotations:
let firstName: string = "Alice";
let lastName: string = "Smith";
let age: number = 25;
let isLoggedIn: boolean = true;
let score: number = 98.5;
let greeting: string = `Hello, ${firstName}!`;
בדיקת שגיאות:
firstName = 42; // ERROR: Type 'number' is not assignable to type 'string'
age = "twenty-five"; // ERROR: Type 'string' is not assignable to type 'number'
isLoggedIn = 1; // ERROR: Type 'number' is not assignable to type 'boolean'
כל שלוש ההשמות נותנות שגיאה. שימו לב שגם isLoggedIn = 1 לא עובד - שלא כמו JS רגיל שמתייחס ל-1 כ-truthy, טייפסקריפט לא מאפשרת להכניס מספר למשתנה בוליאני.
פתרון תרגיל 3¶
let a = 42; // number
let b = "hello"; // string
let c = true; // boolean
let d = [1, 2, 3]; // number[]
let e = { name: "Alice", age: 30 }; // { name: string; age: number }
let f = null; // null
let g = undefined; // undefined
let h = Math.random() > 0.5 ? "yes" : "no"; // string
let i = Math.random() > 0.5 ? 42 : "hello"; // string | number
נקודות מעניינות:
- f מוסק כ-null (לא any) - מה שאומר שאפשר להכניס בו רק null
- g מוסק כ-undefined
- h מוסק כ-string (לא "yes" | "no") כי שני הענפים הם מחרוזות
- i מוסק כ-string | number - טיפוס איחוד, כי TS לא יודעת איזה ענף ירוץ
פתרון תרגיל 4¶
function calculateArea(width: number, height: number): number {
return width * height;
}
function formatName(first: string, last: string): string {
return `${first} ${last}`;
}
function isAdult(age: number): boolean {
return age >= 18;
}
function describePerson(name: string, age: number, city: string = "Unknown"): string {
return `${name} is ${age} years old and lives in ${city}`;
}
let area: number = calculateArea(5.0, 3.0);
let fullName: string = formatName("Alice", "Smith");
let adult: boolean = isAdult(20);
let description: string = describePerson("Bob", 25, "Tel Aviv");
let description2: string = describePerson("Charlie", 30);
console.log(area); // 15
console.log(fullName); // "Alice Smith"
console.log(adult); // true
console.log(description); // "Bob is 25 years old and lives in Tel Aviv"
console.log(description2); // "Charlie is 30 years old and lives in Unknown"
שינויים מפייתון:
- float ו-int הפכו ל-number - בטייפסקריפט יש טיפוס מספרי אחד
- str הפך ל-string
- bool הפך ל-boolean
- def הפך ל-function
- f"..." הפך ל-`...`
- snake_case הפך ל-camelCase
- print() הפך ל-console.log()
הערה: ה-type annotations על המשתנים area, fullName וכו׳ לא הכרחיים - TS יכולה להסיק אותם מערך ההחזרה של הפונקציות. הוספנו אותם כאן לתרגול.
פתרון תרגיל 5¶
// ERROR 1: "25" is a string, not a number
let username: string = "Alice";
let userAge: number = 25; // fixed: removed quotes
let isActive: boolean = true; // fixed: removed quotes
// ERROR 2: function returns string instead of number
function multiply(a: number, b: number): number {
return a * b; // fixed: actual multiplication
}
// ERROR 3: function doesn't always return a string (missing return)
function getGreeting(name: string): string {
if (name) {
return "Hello, " + name;
}
return "Hello, stranger"; // fixed: added else return
}
// ERROR 4: "3" is a string in the array
let numbers: number[] = [1, 2, 3, 4, 5]; // fixed: 3 instead of "3"
// ERROR 5: multiply returns number, not string
let result: number = multiply(5, 3); // fixed: type is number
פתרון תרגיל 6¶
א. בלי strict, הקוד מתקמפל בלי שגיאות. הפרמטר name מקבל טיפוס any בשקט, והגישה ל-value.toString() לא נבדקת.
ב. עם strict, יש שתי שגיאות:
1. Parameter 'name' implicitly has an 'any' type - noImplicitAny דורש טיפוס מפורש
2. 'value' is possibly 'null' - strictNullChecks מונע גישה ל-property של null
ג. התיקונים:
function greet(name: string): void {
console.log("Hello, " + name);
}
let value: string | null = null;
if (value !== null) {
console.log(value.toString());
} else {
console.log("value is null");
}
פתרון תרגיל 7¶
א. התקנה:
ב. קובץ playground.ts:
function square(n: number): number {
return n * n;
}
function repeat(str: string, times: number): string {
let result = "";
for (let i = 0; i < times; i++) {
result += str;
}
return result;
}
console.log(square(5)); // 25
console.log(repeat("ha", 3)); // "hahaha"
הרצה:
ג. השוואה:
- עם tsc + node: שני צעדים - npx tsc ואז node dist/playground.js
- עם tsx: צעד אחד - npx tsx playground.ts
tsx נוח יותר לפיתוח מהיר כי חוסך את צעד הקומפילציה.
פתרון תרגיל 8¶
גרסת JS:
function createProfile(name, age, hobbies) {
return {
name,
age,
hobbies,
summary: `${name} is ${age} years old and enjoys ${hobbies.join(", ")}`
};
}
let profile = createProfile("Alice", 30, ["reading", "coding"]);
console.log(profile);
גרסת TS:
function createProfile(
name: string,
age: number,
hobbies: string[]
): { name: string; age: number; hobbies: string[]; summary: string } {
return {
name,
age,
hobbies,
summary: `${name} is ${age} years old and enjoys ${hobbies.join(", ")}`
};
}
let profile: { name: string; age: number; hobbies: string[]; summary: string } =
createProfile("Alice", 30, ["reading", "coding"]);
console.log(profile);
שימו לב שטיפוס ההחזרה ארוך ומסורבל. בשיעור הבא נלמד על interface ו-type שמאפשרים להגדיר טיפוסים בשם ולמנוע חזרות.
תשובות לשאלות¶
-
טייפסקריפט היא ג׳אווהסקריפט עם טיפוסים סטטיים. היא מוסיפה בדיקת טיפוסים בזמן קומפילציה, שלא קיימת ב-JS. כל קוד JS הוא קוד TS תקין, אבל לא להפך.
-
לא, טייפסקריפט לא רצה ישירות בדפדפן. הדפדפן מבין רק JavaScript. צריך לקמפל את הקוד מ-TS ל-JS לפני שהדפדפן יכול להריץ אותו. הטיפוסים מוסרים בתהליך הקומפילציה.
-
הקומפיילר tsc (TypeScript Compiler) עושה שני דברים: בודק שגיאות טיפוסים, וממיר את הקוד ל-JavaScript על ידי הסרת כל ה-type annotations.
-
strict mode מפעיל את כל הבדיקות המחמירות - strictNullChecks, noImplicitAny, ועוד. בלי strict mode, טייפסקריפט מתעלמת מהרבה שגיאות ומפספסת את רוב היתרונות שלה. זה כמו להרכיב חגורת בטיחות בלי לסגור אותה.
-
בפייתון type hints הם רק רמזים - פייתון לא אוכפת אותם בזמן ריצה. אפשר להעביר int לפונקציה שמצפה ל-str ופייתון לא תתלונן. בטייפסקריפט הטיפוסים נאכפים על ידי הקומפיילר - קוד עם שגיאות טיפוסים לא יתקמפל.
-
type inference (הסקת טיפוסים) היא היכולת של טייפסקריפט להבין את הטיפוס בלי שנכתוב אותו. למשל:
let x = 5- TS יודעת ש-x הוא number בלי שנכתובlet x: number = 5. TS מסתכלת על הערך ומסיקה את הטיפוס. -
חובה לכתוב type annotation בפרמטרים של פונקציות (TS לא מסיקה אותם), במשתנים שמוגדרים בלי ערך התחלתי, וכשרוצים טיפוס ספציפי יותר. אפשר לסמוך על הסקה כשמאתחלים משתנה עם ערך (כמו
let x = 5), ב-return type של פונקציות פשוטות, ובכל מקום ש-TS מסיקה נכון.