日常写JavaScript代码时,你是不是总踩类型的坑?比如input输入的数字实际是字符串、+号既做加法又做拼接导致隐藏bug,排查起来又费时间又头疼。
这篇文章我会带你用3个实战技巧,结合TypeScript解决JS弱类型的痛点,从根本上减少类型错误,还能掌握实用的JS/TS编程技巧,让你的代码更稳、更易维护。
一、先聊聊:为什么JS总出类型问题?
JavaScript是弱类型语言,变量类型可以随意切换,这在开发时看似灵活,实则藏了很多坑:
- 场景1:浏览器input框获取的数值,肉眼看是数字,实际是字符串类型
- 场景2:+号既是加法运算符,又是字符串连接符,一不小心就拼接出错误结果
- 后果:这类问题不会直接报错,却会隐藏在系统里,等发现时已经造成影响
而TypeScript(TS)作为JS的超集,添加了静态类型约束,编译阶段就能检查出类型错误,从源头规避这类问题。
二、实战场景1:处理input输入的类型问题
踩坑示例(JS原生写法)
先看一段有问题的代码,你能发现问题吗?
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Input类型踩坑</title>
</head>
<body>
<input type="text" class="ipt" placeholder="请输入数字">
<script>
// 错误点:getElementById应该传id,这里传了类名;且未处理类型
const ipt = document.getElementById('.ipt');
ipt.addEventListener('change',(e)=>{
// 此时e.target.value是字符串,直接用会踩坑
console.log('输入值类型:', typeof e.target.value);
console.log('输入值+10:', e.target.value + 10);
})
</script>
</body>
</html>
踩坑提醒
document.getElementById参数是元素id,不是类名(正确获取类元素用document.querySelector)- input输入的内容默认是字符串,直接做加法会变成拼接(比如输入5,结果是"510")
修复后的实战代码
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Input类型修复</title>
</head>
<body>
<input type="text" class="ipt" placeholder="请输入数字">
<script>
// 正确获取类元素
const ipt = document.querySelector('.ipt');
ipt.addEventListener('change',(e)=>{
// 强制类型转换为数字
const num = Number(e.target.value);
console.log('转换后类型:', typeof num);
console.log('输入值+10:', num + 10);
})
</script>
</body>
</html>
关键要点
- 用
document.querySelector获取类/选择器元素,getElementById只传id - 拿到input值后,用
Number()/+变量强制转换为数字类型,避免字符串拼接坑
三、实战场景2:用TS约束函数参数和返回值
踩坑示例(JS函数无类型约束)
javascript
// 加法函数,却可能返回拼接结果
function add(a, b) {
return a + b;
}
// 看似正常,实际b是字符串,结果变成"12"
let a = 1;
let b = "2";
console.log(add(a, b));
修复后的TS写法(可直接运行)
typescript
// 明确约束参数a/b为number类型,返回值也为number
function add(a: number, b: number): number {
return a + b; // 此时+号只会做加法,不会拼接
}
let a = 1;
let b = "2";
// 强制转换b为数字,TS编译阶段会检查类型
let num: number = add(a, +b);
console.log(num); // 输出3,正确

踩坑提醒
- TS需要先编译为JS才能运行(可借助Bun/tsc工具)
- 定义TS变量时,用
变量名: 类型明确约束,编译阶段就能发现类型错误 +变量是隐式类型转换,和Number(变量)效果一致,推荐根据场景选择
四、实战场景3:封装实用的sleep函数(异步同步化)
日常开发中,经常需要延迟执行代码,比如等待接口返回、定时操作,手写setTimeout容易嵌套,用Promise封装sleep函数更优雅:
完整可运行代码
javascript
// 封装sleep函数,延迟t毫秒后执行
function sleep(t) {
// 用Promise封装setTimeout,解决异步嵌套问题
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve();
}, t);
});
}
// 异步函数中使用await,实现异步任务同步化
async function main() {
console.log('--开始执行--');
await sleep(2000); // 延迟2秒
console.log('--2秒后执行--');
}
// 执行函数
main();
关键要点
await只能用在async函数中,后面跟Promise对象- sleep函数返回Promise,通过
resolve标记异步任务完成 - 这种写法比纯setTimeout更易读,避免回调地狱
五、加分项:用Bun提升TS/JS运行效率
Bun是比Node.js更快的JS/TS运行时+包管理器,零配置开箱即用,是Node.js优化的升级版,性能优势明显。
日常开发中,用Bun运行TS/JS文件无需额外配置,直接:
bash
# 运行TS文件
bun run 1.ts
# 运行JS文件
bun run 3.js
相比Node.js,Bun启动更快、编译TS更高效,能显著提升开发效率。
六、总结
- JS弱类型的核心坑:类型隐式转换、运算符歧义,TS的静态类型约束能从编译阶段规避
- 处理input输入:先转换类型(Number/+变量),再做数值运算
- TS写函数:明确约束参数/返回值类型,减少隐藏bug
- 异步延迟:用Promise封装sleep函数,async/await让异步代码更易读
- 工具选择:Bun替代Node.js,提升TS/JS运行和编译效率
这些技巧都是日常开发高频用到的,把它们融入到代码中,能大幅减少类型错误,提升代码稳定性。