כדי להמיר מחרוזת למספר ב-TypeScript, קראו ל-Number(text). לתוצאה יש טיפוס number, והיא NaN כשהטקסט אינו מספר תקין. לטקסט עם תווים נוספים בסוף, כמו "42px", השתמשו ב-parseInt(text, 10) או ב-parseFloat(text).
כל ארבע ההמרות מחזירות את הטיפוס number. TypeScript לא יודע אם הטקסט היה תקין; מחרוזת לא תקינה עדיין נותנת number, שהערך שלו הוא NaN.
למה חייבים להמיר
שדות טופס, פרמטרים של URL, משתני סביבה ותוכן של קבצים מגיעים כמחרוזות. TypeScript לא ייתן לכם להשתמש במחרוזת במקום שבו מצופה מספר:
index.ts(3,23): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
חשבון עם -, * ו-/ על מחרוזת הוא שגיאה. + מותר אבל משרשר, כך ש-"3" + 10 הוא המחרוזת "310", ולכן ההמרה חייבת לבוא קודם: Number(quantity) * 10.
גם type assertion לא עוזר. quantity as number נדחה (TS2352), וכפייה דרך as unknown as number רק משתיקה את הקומפיילר: בזמן ריצה הערך נשאר מחרוזת.
Number מול parseInt מול parseFloat מול + אונרי
ארבע הפונקציות מסכימות על קלט נקי ולא מסכימות על כל השאר. הטבלה הזו היא הפלט האמיתי של כל אחת מהן ב-Node:
| קלט | Number(s) | +s | parseInt(s, 10) | parseFloat(s) |
|---|---|---|---|---|
"42" | 42 | 42 | 42 | 42 |
"3.99" | 3.99 | 3.99 | 3 | 3.99 |
"42px" | NaN | NaN | 42 | 42 |
"" | 0 | 0 | NaN | NaN |
" 3 " | 3 | 3 | 3 | 3 |
"1e3" | 1000 | 1000 | 1 | 1000 |
"0x1F" | 31 | 31 | 0 | 0 |
"1,000" | NaN | NaN | 1 | 1 |
"12_000" | NaN | NaN | 12 | 12 |
"abc" | NaN | NaN | NaN | NaN |
הכללים שמאחורי הטבלה:
Numberו-+אונרי זהים. הם ממירים את כל המחרוזת אחרי הסרת רווחים מהקצוות, מבינים1e3ו-hex עם0x, ומחזיריםNaNאם נשאר משהו. מחרוזת ריקה או כזו שיש בה רק רווחים הופכת ל-0.parseIntו-parseFloatקוראים מההתחלה ועוצרים בתו הראשון שאינם יכולים להשתמש בו, ולכן"42px"ו-"1,000"נותנים מספרים חלקיים. מחרוזת ריקה היאNaN.parseIntמשמיט את החלק העשרוני ולא מבין מעריכים:"1e3"נעצר ב-e.- מפרידים מספריים (
12_000) תקינים בקוד מקור, לא במחרוזות.
Number היא הבחירה המחמירה יותר לבדיקת קלט. parseInt ו-parseFloat מתאימים לטקסט שבאמת נושא יחידה או סיומת, כמו גדלים ב-CSS.
טיפול בקלט לא תקין: NaN
ל-NaN יש טיפוס number, ולכן הקומפיילר אף פעם לא מזהיר עליו. בדקו את התוצאה בעצמכם, עם Number.isNaN או Number.isFinite:
החזרה של number | undefined הופכת את הכישלון לחלק מהטיפוס, כך שכל מי שקורא לפונקציה חייב לטפל בו לפני שהוא עושה חשבון. Number.isFinite דוחה גם את Infinity, ש-Number("Infinity") מחזיר בלי בעיה.
הימנעו מ-isNaN(x) הגלובלי: הוא ממיר קודם את הארגומנט שלו, ולכן isNaN("abc") הוא true ב-JavaScript. ההצהרה של TypeScript מקבלת רק number, כך שהעברת מחרוזת היא השגיאה TS2345, וזה רמז להשתמש ב-Number.isNaN על ערך שכבר הומר.
מחרוזת למספר שלם
תמיד העבירו ל-parseInt את הארגומנט השני שלו, ה-radix: 10 לטקסט עשרוני. הוא אופציונלי, אבל הוא מתעד את הכוונה וחשוב לבסיסים אחרים. כדי לקבל מספר שלם ממחרוזת עשרונית, המירו ואז עגלו במפורש.
parseInt מצפה למחרוזת: parseInt(12.7) היא שגיאת קומפילציה (TS2345), וזה שימושי, כי ב-JavaScript parseInt על מספר ממיר אותו קודם לטקסט ונותן תשובות שגויות לערכים כמו 0.0000005 (הוא מחזיר 5). השתמשו ב-Math.trunc למספרים. למספרים שלמים מעבר ל-Number.MAX_SAFE_INTEGER, BigInt(text) מפרש את הערך המלא (וזורק SyntaxError על טקסט לא תקין במקום להחזיר NaN).
מספר למחרוזת
כל אחד מ-String(n), n.toString() ו-`${n}` ממיר מספר לצורת המחרוזת הקצרה ביותר שלו. מתודות עיצוב נותנות יותר שליטה:
toFixed מעגל את הערך הבינארי, לא את המספר העשרוני שהקלדתם, ולכן (1.005).toFixed(2) הוא "1.00": 1.005 נשמר כערך קטן מעט מ-1.005. לכסף, שמרו סכומים כאגורות שלמות או עצבו אותם עם Intl.NumberFormat.
String(n) עובד גם על null ו-undefined (ונותן "null" ו-"undefined"), במקום שבו n.toString() היה שגיאת קומפילציה תחת strict, כי הערך עשוי להיות חסר.
סיכום מהיר
| משימה | קוד | טיפוס התוצאה |
|---|---|---|
| מחרוזת למספר, בצורה מחמירה | Number(s) או +s | number (אולי NaN) |
| מספר שלם מתחילת הטקסט | parseInt(s, 10) | number (אולי NaN) |
| מספר עשרוני מתחילת הטקסט | parseFloat(s) | number (אולי NaN) |
| בדיקת התוצאה | Number.isFinite(n), Number.isNaN(n) | boolean |
| מספר שלם גדול | BigInt(s) | bigint |
| מספר למחרוזת | String(n), n.toString(), `${n}` | string |
| מספר קבוע של ספרות עשרוניות | n.toFixed(2) | string |
| בסיס אחר | n.toString(16) | string |
| מפרידי אלפים | n.toLocaleString("en-US") | string |
שאלות נפוצות
איך ממירים מחרוזת למספר ב-TypeScript?
השתמשו ב-Number(text). הוא מחזיר number: את הערך לטקסט מספרי תקין, NaN לכל דבר אחר, ו-0 למחרוזת ריקה או כזו שיש בה רק רווחים. השתמשו ב-parseInt(text, 10) או ב-parseFloat(text) כשבטקסט עשויים להיות תווים נוספים בסוף, כמו "42px".
אפשר להמיר מחרוזת למספר עם as number?
as number?לא. "42" as number היא שגיאת קומפילציה (TS2352), וגם כשכופים אותה דרך unknown, assertion משנה רק את הטיפוס שהקומפיילר רואה: בזמן ריצה הערך הוא עדיין המחרוזת "42". המירו את הערך עם Number(), parseInt() או parseFloat().
מה ההבדל בין Number() ל-parseInt() ב-TypeScript?
Number ממיר את כל המחרוזת ומחזיר NaN אם חלק כלשהו ממנה אינו מספרי, ולכן Number("42px") הוא NaN. parseInt קורא ספרות מההתחלה ועוצר בתו הראשון שאינו ספרה, ולכן parseInt("42px", 10) הוא 42, והוא משמיט את החלק העשרוני. Number("") הוא 0, ואילו parseInt("") הוא NaN.
איך בודקים אם מחרוזת היא מספר תקין?
המירו אותה ובדקו את התוצאה: const n = Number(text); if (text.trim() !== "" && Number.isFinite(n)) { ... }. הבדיקה של מחרוזת ריקה חשובה, כי Number("") הוא 0. השתמשו ב-Number.isNaN, לא ב-isNaN הגלובלי, ש-TypeScript ממילא מקבל רק עם ארגומנט מסוג number.
איך ממירים מספר למחרוזת ב-TypeScript?
String(n), n.toString() או template literal `${n}` נותנים כולם את אותה תוצאה. השתמשו ב-n.toFixed(2) למספר קבוע של ספרות אחרי הנקודה, ב-n.toString(16) לבסיס אחר, וב-n.toLocaleString("en-US") למפרידי אלפים.