TypeScript 常见坑有哪些
早上在群里聊技术时,刚工作两年的小周突然发了一串哀嚎:“我写的代码明明看了几遍没报错,运行时直接崩了,查了半天才发现是TypeScript的锅!”其实不止小周,不少刚接触TypeScript的前端开发者,都踩过这个“看起来严谨,实则藏坑”的语言的雷。TypeScript虽然能帮我们提前发现不少错误,但它不是“万能保护伞”,不少隐蔽的坑稍不注意就会踩中,今天就用几个生活化的例子,把这些常见坑讲明白。
第一个坑:类型的“宽松自动推导”
刚学TypeScript的人,最容易犯的错就是依赖自动类型推导,觉得“只要编辑器没红波浪线就没问题”。举个例子,你写了一个简单的函数:

`typescript
function add(a, b) {
return a + b;
}
`
TypeScript会自动给这个函数的参数a和b推导成any类型——就像你给外卖备注“随便装”,商家(TypeScript)不会特意检查你装了什么,结果你后来用的时候,传了add(10, "5"),编辑器没报错,运行时却返回"105",和你预期的15完全不一样。
解决办法很简单,给函数参数明确标上类型:function add(a: number, b: number),就像点外卖时备注“要加2勺糖、少放辣”,商家(TypeScript)就会严格按照要求来,不会再乱装东西。
第二个坑:联合类型的“窄化遗漏”
联合类型是TypeScript用来处理“多种可能类型”的功能,比如你要写一个函数,参数可能是字符串也可能是数字,就会用string | number。但不少人用的时候会犯一个错:只在函数开头判断了类型,后面就直接当其中一种类型用。
比如你写了一个获取长度的函数:
`typescript
function getLength(value: string | number) {
if (typeof value === "string") {
return value.length;
}
return value;
}
`
这里的问题是,函数返回的可能是number(当参数是数字时),但你要是把这个返回值传给另一个要求string类型的函数,TypeScript会报错吗?等等,要是你后来加了个分支,比如想对数字参数也做处理:
`typescript
function getLength(value: string | number) {
if (typeof value === "string") {
return value.length;
} else if (typeof value === "number") {
return value.toString().length;
}
// 要是不小心漏了这个else分支,TypeScript会认为这里可能返回undefined
// 但不会立刻标红,你继续用的时候就会出现“undefined.length”的运行错误
}
`
这就像你要给手机充电,明确说“要么插充电线,要么插无线充电座”,结果你只准备了充电线,却忘了检查无线充电的情况,出门前觉得“都准备了”,到地方才发现无线座没带,充不了电。解决办法是给联合类型的所有可能都做判断,或者用类型守卫明确窄化范围,别留“漏网之鱼”。
第三个坑:对象的“可选属性疏忽”
对象的可选属性是TypeScript里很实用的功能,比如你写一个用户信息对象,名字是必填的,年龄是可选的,就会用{ name: string; age?: number }。但很多人用的时候会不小心“忘记可选属性可能不存在”,就像你给朋友发消息“有空来我家玩,我家有沙发(可选的),你要是带个抱枕也可以”,结果你一坐下就想抱抱枕,却忘了朋友根本没带。
举个实际例子:
`typescript
interface User {
name: string;
age?: number;
}
function getUserAge(user: User) {
return user.age.toFixed();
}
`
要是某个用户的age没填,调用这个函数时,TypeScript编辑器不会立刻标红,但运行时会直接报错——就像你没带抱枕,却硬要抱,结果摔了。解决办法是在使用可选属性前,先判断它是否存在,比如return user.age?.toFixed(),加上可选链操作符,就像你抱抱枕前先看看手里有没有,没有就不抱,不会出错。
TypeScript的这些坑,本质上都是“对类型规则的疏忽”,只要多注意明确类型、完整判断分支、小心处理可选值,就能避开大部分问题。不用怕踩坑,只要平时写代码时多留个心眼,这些坑反而会帮你更懂TypeScript的规则,写出更稳定的代码。