引言:为什么简单的任务会破坏代码
\n\n每个使用 TypeScript 的开发人员迟早都会遇到这样一个任务:“如何将字符串转换为数字?”看起来再简单不过了?但正是这个看似简单的操作,却成为数十个 Bug 的源头,尤其是在前端和后端交界处,数据来自输入表单、API 或 CSV 解析时。
\n\n在 Stack Overflow 上,问题 “How to convert a string to number in TypeScript?” 获得了数万次浏览。这并非偶然。开发人员常常陷入各种细节:NaN、parseInt 与 Number() 的对比、精度丢失以及空字符串的意外行为。在本文中,我们将分析 TypeScript 中字符串转数字的常见错误,并展示如何避免它们。您将了解针对特定任务应选择哪种方法,以及如何编写真正可靠的代码。
TypeScript 中字符串转数字的主要方法
\n\n在讨论错误之前,让我们回顾一下 TypeScript 开发人员可用的工具。每种方法的行为都不同,选择错误的方法就是第一个也是最重要的错误。
\n\n1. Number() 函数
\n最直接的方法。Number(value) 尝试将传入的值转换为数字。如果无法转换,则返回 NaN。
const str: string = "42";\nconst num: number = Number(str);\nconsole.log(num); // 42\n\nconst invalid: string = "hello";\nconst badNum: number = Number(invalid);\nconsole.log(badNum); // NaN\n\n2. 一元加号 (+)
\n简洁的语法,功能与 Number() 相同。虽然简洁,但可能会让新手感到困惑。
const price: string = "99.99";\nconst numericPrice: number = +price;\nconsole.log(numericPrice); // 99.99\n\nconst empty: string = "";\nconst zero: number = +empty;\nconsole.log(zero); // 0 — 注意,这是一个常见的陷阱!\n\n3. parseInt() 和 parseFloat()
\n用于解析整数和浮点数的专用函数。它们从字符串中“截取”数字部分,忽略后续字符。
\n\nconst userInput: string = "123px";\nconst width: number = parseInt(userInput, 10);\nconsole.log(width); // 123 — 字符 'px' 被丢弃\n\nconst height: string = "45.67em";\nconst parsedHeight: number = parseFloat(height);\nconsole.log(parsedHeight); // 45.67\n\n4. 位运算符 (~~, | 0)
\n一种源自 JavaScript 的奇特方法。仅适用于整数,并会丢弃小数部分。
\n\nconst str: string = "7.8";\nconst result: number = ~~str;\nconsole.log(result); // 7 — 小数部分丢失\n\nTypeScript 中字符串转数字的 5 大错误
\n\n现在我们已经了解了工具,让我们看看开发人员最常在哪里犯错。这些错误是真正的“陷阱”,即使是经验丰富的程序员也会中招。
\n\n错误 #1:忽略 NaN
\n最常见的错误是不检查结果是否为 NaN。TypeScript 不会在算术运算或比较中使用 NaN 时报错,但结果会出乎意料。
const input: string = "not a number";\nconst value: number = Number(input);\n\n// 错误:NaN 参与计算\nconst total = value + 10;\nconsole.log(total); // NaN\n\n// 与 NaN 的比较始终为假\nif (value === NaN) {\n console.log("这永远不会执行");\n}\n\n如何避免:始终使用 isNaN() 或 Number.isNaN() 进行检查。推荐使用后者,因为它不会对非数值类型进行强制转换。
if (Number.isNaN(value)) {\n console.error("输入的不是数字");\n // 可以返回默认值或显示错误