前言
在 JavaScript 生态快速演进的今天,TypeScript 和 Bun 的出现极大提升了开发效率。TypeScript 为 JavaScript 带来了类型安全,而 Bun 则提供了比 Node.js 更快的运行速度和开箱即用的体验。本文将结合代码示例,带你快速理解这两者的核心价值,并重点讲解 TypeScript 中如何安全地将文本类型转换为数字类型------这是前端开发中最常见的类型处理场景之一。
一、TypeScript:为 JavaScript 加上类型约束
JavaScript 是一门弱类型语言,这意味着:
- 变量类型可以在运行时动态改变;
+号既可以表示加法,也可以是字符串拼接;- 类型错误往往在运行时才暴露,容易隐藏 Bug。
TypeScript 作为 JavaScript 的超集,最大的特点就是静态类型检查。
基础类型示例
typescript
typescript
// 1.ts
const nickname: string = "9527";
const age: number = 18; // 如果赋值字符串会报错
console.log(`我是${nickname},我今年${age}`);
函数参数类型约束
typescript
typescript
// 2.ts
function add(a: number, b: number) {
return a + b;
}
let a = 9;
let b = "1";
// 编译阶段就会报错:类型"string"的参数不能赋给类型"number"的参数
// console.log(add(a, b));
// 正确的做法:显式转换
console.log(add(a, Number(b))); // 输出 10
类型检查不仅提升了代码健壮性,也让 IDE 能提供更精准的智能提示。
二、核心专题:TypeScript 中将文本类型改变为数字类型
在实际开发中,从用户输入、URL 参数、本地存储、API 响应中获取的数据往往是字符串格式,但我们需要将其作为数字进行计算。TypeScript 提供了多种方式来实现文本到数字的安全转换。
2.1 为什么需要转换?
typescript
javascript
// 常见问题示例
let userInput = "100"; // 模拟表单输入,永远是字符串
let userScore = "50"; // 从 localStorage 获取
// 错误的做法:直接相加
let total = userInput + userScore; // "10050" 字符串拼接,不是预期结果
console.log(total, typeof total); // "10050" "string"
// 正确的做法:先转换再计算
let correctTotal = Number(userInput) + Number(userScore); // 150
console.log(correctTotal, typeof correctTotal); // 150 "number"
2.2 五种文本转数字的方法
方法一:Number() 构造函数(最推荐)
typescript
typescript
// 最常用、最直观的方法
let strNum1: string = "123";
let num1: number = Number(strNum1);
console.log(num1, typeof num1); // 123 "number"
// 处理边界情况
console.log(Number("123.45")); // 123.45
console.log(Number("")); // 0
console.log(Number(" ")); // 0
console.log(Number("abc")); // NaN (Not a Number)
console.log(Number(true)); // 1
console.log(Number(false)); // 0
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
方法二:parseInt() 整数转换
typescript
typescript
// 转换为整数,可指定进制
let strNum2: string = "123.45";
let num2: number = parseInt(strNum2);
console.log(num2); // 123(舍弃小数部分)
// 带进制的转换
let hexStr: string = "FF";
let numHex: number = parseInt(hexStr, 16);
console.log(numHex); // 255
// 自动忽略非数字开头后的内容
console.log(parseInt("123px")); // 123
console.log(parseInt("abc123")); // NaN(以非数字开头)
console.log(parseInt("12.34")); // 12
方法三:parseFloat() 浮点数转换
typescript
typescript
// 保留小数部分
let strNum3: string = "123.45";
let num3: number = parseFloat(strNum3);
console.log(num3); // 123.45
// 对比 parseInt
console.log(parseFloat("123.45")); // 123.45
console.log(parseInt("123.45")); // 123
// 自动忽略非数字开头后的内容
console.log(parseFloat("123.45px")); // 123.45
console.log(parseFloat("12.34.56")); // 12.34(只解析第一个有效数字)
方法四:一元加运算符 +(最简洁)
typescript
typescript
// 最简洁的写法,性能最好
let strNum4: string = "123";
let num4: number = +strNum4;
console.log(num4, typeof num4); // 123 "number"
// 实际应用场景(改写 2.ts 的例子)
function add(a: number, b: number) {
return a + b;
}
let inputX: string = "9";
let inputY: string = "1";
let result: number = add(+inputX, +inputY); // 使用 + 进行转换
console.log(result); // 10
方法五:位运算技巧(不推荐,仅供了解)
typescript
typescript
// 位运算会强制转换为 32 位整数
let strNum5: string = "123.45";
let num5: number = ~~strNum5; // 双非按位取反
console.log(num5); // 123
let num6: number = strNum5 | 0; // 按位或
console.log(num6); // 123
// 注意:只能处理整数,且范围受限
console.log(~~"9999999999"); // 1410065407(溢出!)
2.3 方法对比总结
| 方法 | 示例 | 小数支持 | 空字符串 | 非数字字符串 | 性能 | 推荐度 |
|---|---|---|---|---|---|---|
Number() |
Number("123") |
✅ | 0 | NaN | 中等 | ⭐⭐⭐⭐⭐ |
parseInt() |
parseInt("123") |
❌(舍弃) | NaN | NaN | 快 | ⭐⭐⭐⭐ |
parseFloat() |
parseFloat("123.45") |
✅ | NaN | NaN | 快 | ⭐⭐⭐⭐ |
一元加 + |
+"123" |
✅ | 0 | NaN | 最快 | ⭐⭐⭐⭐⭐ |
| 位运算 | ~~"123" |
❌ | 0 | 0 | 快 | ⭐⭐ |
四、结合 Bun + TypeScript 调用大模型 API
下面是一个实际例子:使用 axios 调用 DeepSeek 模型接口。
typescript
javascript
// index.ts
import axios from "axios";
async function chat() {
try {
const res = await axios.post(
`${process.env.DEEPSEEK_BASE_URL}`,
{
model: "deepseek-v4-flash",
messages: [{ role: "user", content: "你好,介绍一下Bun" }],
},
{
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.DEEPSEEK_API_KEY}`,
},
}
);
console.log(res.data.choices[0].message.content);
} catch (err) {
console.log(err);
}
}
chat();
注意:需要在项目根目录配置
.env文件,例如:text
iniDEEPSEEK_BASE_URL=https://api.deepseek.com/v1/chat/completions DEEPSEEK_API_KEY=your-api-key
五、封装异步任务:Sleep 函数示例
Bun 和 Node.js 都支持 Promise 与 async/await。下面是一个经典的 sleep 封装:
javascript
javascript
// 3.js
function sleep(t) {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, t);
});
}
async function main() {
console.log("--start--");
await sleep(2000); // 等待 2 秒
console.log("--end--");
}
main();
这种模式在需要控制执行流程、模拟延迟或实现轮询时非常实用。
六、综合实战:完整的类型转换 + API 调用示例
typescript
typescript
// 完整示例:处理用户输入并调用 API
interface UserData {
id: string;
age: string;
score: string;
}
function validateAndProcessUser(user: UserData): { id: number; age: number; score: number } {
// 类型转换 + 验证
const id = Number(user.id);
const age = parseInt(user.age, 10);
const score = parseFloat(user.score);
if (isNaN(id) || id <= 0) {
throw new Error("无效的用户ID");
}
if (isNaN(age) || age < 0 || age > 150) {
throw new Error("无效的年龄");
}
if (isNaN(score) || score < 0 || score > 100) {
throw new Error("无效的分数");
}
return { id, age, score };
}
// 使用示例
const rawUser: UserData = {
id: "123",
age: "25",
score: "95.5"
};
try {
const processed = validateAndProcessUser(rawUser);
console.log(`用户 ${processed.id},年龄 ${processed.age},分数 ${processed.score}`);
} catch (error) {
console.error(error.message);
}
总结
| 特性 | TypeScript | Bun |
|---|---|---|
| 类型系统 | 静态类型,编译时检查 | 原生支持 TS,无需额外配置 |
| 运行速度 | 编译后运行,性能略低于原生 JS | 极快的启动与执行 |
| 适用场景 | 大型项目、团队协作 | 高性能脚本、AI Agent 开发 |
| 社区与工具链 | 成熟,与 VSCode 深度集成 | 新兴,集成包管理器与测试工具 |
文本转数字的最佳实践回顾
| 场景 | 推荐方法 | 示例 |
|---|---|---|
| 普通字符串转数字 | Number() 或 + |
Number("123") / +"123" |
| 提取整数(如 "123px") | parseInt(str, 10) |
parseInt("123px", 10) |
| 提取浮点数(如 "123.45px") | parseFloat() |
parseFloat("123.45px") |
| 批量数组转换 | map(Number) |
["1","2"].map(Number) |
| 需要默认值 | 自定义函数 | toNumber(value, 0) |
TypeScript 让 JavaScript 更安全,Bun 让它更快。而掌握类型转换技巧,则是构建健壮应用的基础。两者结合,能够显著提升开发体验与项目质量。
如果你正在构建下一个 AI Agent 或高性能后端服务,不妨试试 Bun + TypeScript 的组合,并时刻牢记:用户输入永远是字符串,显式转换才是王道!