פונקציה ב-TypeScript היא פונקציית JavaScript עם טיפוסים על הפרמטרים שלה, ואם רוצים, גם על ערך ההחזרה. כל פרמטר מקבל הערת טיפוס, טיפוס ההחזרה נכתב אחרי רשימת הפרמטרים, והקומפיילר בודק כל קריאה מול שניהם.
שתי הקריאות השגויות הן שגיאות בזמן קומפילציה (TS2345 ו-TS2554). ההערות // @ts-expect-error אומרות לקומפיילר שצפויה שגיאה בשורה הבאה, כך ששאר הקובץ עדיין רץ. הסירו אחת מהן והריצו שוב כדי לראות את ההודעה האמיתית.
טיפוסי פרמטרים
כל פרמטר נכתב name: Type. תחת strict, שפועל כברירת מחדל ב-TypeScript 7, פרמטר בלי הערת טיפוס ובלי הקשר שממנו אפשר להסיק הוא שגיאה: Parameter 'x' implicitly has an 'any' type. (TS7006). לכן בפועל כל פרמטר של פונקציה עצמאית מקבל הערת טיפוס.
כל טיפוס יכול לשמש כטיפוס של פרמטר: טיפוסים פרימיטיביים, מערכים, טיפוסי אובייקט, unions ופונקציות אחרות.
TypeScript בודק גם את מספר הארגומנטים. העברה של יותר או פחות ארגומנטים ממה שהפונקציה מצהירה היא שגיאה, בניגוד ל-JavaScript רגיל, שממלא ארגומנטים חסרים ב-undefined ומתעלם מעודפים. כדי להפוך פרמטר לאופציונלי או לתת לו ערך ברירת מחדל, ראו פרמטרים אופציונליים.
טיפוסי החזרה: לכתוב או להסיק
טיפוס ההחזרה בא אחרי הסוגר של רשימת הפרמטרים: function f(): Type. הוא אופציונלי. בלעדיו, TypeScript מסיק את הטיפוס מכל return בגוף הפונקציה.
הערת טיפוס מצדיקה את מקומה כשהפונקציה מיוצאת, כשיש לה כמה מסלולי החזרה, או כשהיא רקורסיבית. השגיאה מופיעה אז בתוך הפונקציה, ב-return השגוי, ולא אצל מי שקורא לה. מקרה קלאסי הוא ענף ששוכח להחזיר ערך:
הקומפיילר מדווח index.ts(2,32): error TS2366: Function lacks ending return statement and return type does not include 'undefined'. הוסיפו return "C"; בסוף והקוד ירוץ. בלי ההערה : string הפונקציה הייתה מתקמפלת עם הטיפוס המוסק "A" | "B" | undefined, והבעיה הייתה עוברת למי שמשתמש בתוצאה.
void: פונקציות שלא מחזירות כלום
לפונקציה שרק עושה משהו (כותבת ללוג, שומרת, משנה נתונים) יש טיפוס ההחזרה void. זה מה ש-TypeScript מסיק כשאין return עם ערך, ואפשר גם לכתוב אותו במפורש.
הכללים האלה על void מפתיעים אנשים:
| מצב | מותר? |
|---|---|
function f(): void { return 42; } | לא: Type 'number' is not assignable to type 'void'. (TS2322) |
const f: () => void = () => 42; | כן: הערך מוחזר, אבל מי שקורא לפונקציה לא יכול לסמוך עליו |
function f(): undefined {} | כן (מ-TypeScript 5.1 ואילך) |
שימוש בתוצאה של פונקציית void בתוך if | לא: An expression of type 'void' cannot be tested for truthiness. (TS1345) |
השורה השנייה מכוונת. בגללה arr.forEach(x => list.push(x)) מתקמפל, למרות ש-push מחזיר מספר. void בטיפוס של פונקציה אומר "לא משנה מה זה מחזיר, אף אחד לא קורא את זה". לפונקציה שאף פעם לא מסיימת (היא תמיד זורקת שגיאה או נכנסת ללולאה אינסופית), טיפוס ההחזרה הוא never.
פונקציות חץ ו-function expressions
פונקציות חץ ו-function expressions מקבלות את אותן הערות טיפוס. טיפוס ההחזרה בא אחרי רשימת הפרמטרים, לפני =>.
בלי הסוגריים, (x, y) => { x, y } הוא בלוק בלי return, והפונקציה מחזירה undefined. כללי זמן הריצה של פונקציות חץ (אין להן this משלהן, אין arguments) זהים לאלה של JavaScript; ראו פונקציות חץ ב-JavaScript.
כשפונקציה נכתבת ישירות כארגומנט, בדרך כלל לא כותבים טיפוסים לפרמטרים שלה בכלל. TypeScript יודע מה ה-callback מקבל מתוך הפונקציה שאליה הוא מועבר (contextual typing): ב-[1, 2].map(n => n * 2), ה-n כבר number. כתיבת הטיפוס של פונקציה כערך, (n: number) => string, מוסברת בעמוד על טיפוסי פונקציות.
החזרה של כמה ערכים
פונקציה מחזירה ערך אחד, אז החזירו אובייקט או tuple ועשו להם destructuring.
טיפוס ההחזרה מסוג tuple צריך הערת טיפוס. בלעדיה, [a, b] מוסק כ-string[]: ה-destructuring עדיין עובד, אבל הטיפוס כבר לא אומר שיש בדיוק שני איברים.
פונקציות async
פונקציית async תמיד מחזירה Promise. כתבו את טיפוס ההחזרה בתור Promise<T>, כאשר T הוא מה שהפונקציה מחזירה בפנים.
async function loadScore(id: number): Promise<number> {
await new Promise((resolve) => setTimeout(resolve, 10));
return id * 10;
}
async function main(): Promise<void> {
const score = await loadScore(4); // score: number
console.log("score", score);
}
main();
הכתיבה async function f(): number היא שגיאה: The return type of an async function or method must be the global Promise<T> type. Did you mean to write 'Promise<number>'? (TS1064).
הפרמטר this
JavaScript קובע את this בזמן הקריאה. TypeScript מאפשר להצהיר מה this חייב להיות, עם פרמטר ראשון מדומה בשם this. הוא מוסר מה-JavaScript המקומפל, ומי שקורא לפונקציה לא מעביר אותו.
interface Counter {
count: number;
}
function increment(this: Counter, by: number): void {
this.count += by;
}
const c = { count: 0, increment };
c.increment(2); // fine: this is c
increment(2);
// error TS2684: The 'this' context of type 'void' is not assignable to method's 'this' of type 'Counter'.
בלי הפרמטר this, ה-this בתוך פונקציה עצמאית הוא any מרומז, ומצב strict מדווח 'this' implicitly has type 'any' because it does not have a type annotation. (TS2683). במתודות של מחלקה this כבר מקבל את הטיפוס של המופע, ולכן הפרמטר שימושי בעיקר לפונקציות עצמאיות שמוצמדות לאובייקטים ול-callbacks שספריות קוראות להם עם this מסוים.
שאלות נפוצות
איך מגדירים טיפוס החזרה לפונקציה ב-TypeScript?
כותבים נקודתיים ואת הטיפוס אחרי רשימת הפרמטרים: function total(a: number, b: number): number { ... }. בפונקציית חץ הוא נכתב באותו מקום: const total = (a: number, b: number): number => a + b;. אם משמיטים אותו, TypeScript מסיק את טיפוס ההחזרה מפקודות ה-return.
האם תמיד צריך לכתוב את טיפוס ההחזרה ב-TypeScript?
זה אופציונלי, כי טיפוס ההחזרה מוסק. כתבו אותו בפונקציות שמיוצאות ובפונקציות עם כמה מסלולי return: ההערה מתעדת את החוזה, ו-return שגוי מדווח אז בתוך הפונקציה ולא אצל קוד רחוק שקורא לה.
מה ההבדל בין void ל-undefined ב-TypeScript?
void אומר "מי שקורא לפונקציה לא אמור להשתמש בערך ההחזרה". undefined הוא טיפוס של ערך מוחשי. פונקציה שמוצהרת (): void לא יכולה להחזיר ערך, אבל טיפוס callback מהצורה () => void מקבל פונקציה שכן מחזירה משהו, והתוצאה פשוט לא נקראת. השתמשו ב-void לפונקציות שלא מחזירות כלום, וב-undefined רק כשמי שקורא באמת משווה את התוצאה ל-undefined.
איך מחזירים כמה ערכים מפונקציה ב-TypeScript?
מחזירים אובייקט ({ min: number; max: number }) או tuple ([number, number]) ועושים לו destructuring במקום הקריאה. אובייקטים ברורים יותר כשלערכים יש משמעויות שונות; tuples נקראים טוב בזוגות קצרים כמו [value, setValue].
מה טיפוס ההחזרה של פונקציה async ב-TypeScript?
תמיד Promise. לפונקציית async שמחזירה number יש טיפוס ההחזרה Promise<number>, וכתיבה של : number עליה היא שגיאת קומפילציה (TS1064). פונקציה שלא מחזירה כלום היא Promise<void>.