TypeScript 如何做类型安全
你有没有过这样的经历:写JavaScript代码时,明明以为传的是数字,结果不小心传了个字符串,运行时直接弹出“undefined is not a function”的错误,查半天也找不到哪里出的问题?这种“看不见的坑”,就是很多JS开发者的噩梦。而TypeScript(简称TS)的出现,很大程度上就是为了填这类坑,其中最核心的能力就是“类型安全”。
什么是类型安全?用买菜打比方就懂
咱们先不用术语,用买菜的场景来理解。假设你要去买“1斤青菜”,如果是JS的话,你可能拿个袋子就装,不管是1斤、1斤半,甚至是1把,都能装;要是拿错了装成了“猪肉”,老板也不会拦你,结果回家发现买错了菜,白跑一趟。

但TS的类型安全,就像有个认真的帮你拎菜的人,你说要“斤数为数字的青菜”,它就会盯着:传的得是数字(比如1),不能是字符串(比如“1斤”),也不能是别的东西(比如猪肉);等你要称重付款时,它还会检查:你给的钱数是不是数字,不能是“现金”“微信”这种字符串,要是有不对,它直接在你写代码的时候就报错,而不是等运行后再出问题。
简单说,类型安全就是让代码里的每一个值,都得“说清楚自己是什么类型”,不能随便乱来,从根源上减少“因为类型错导致的bug”。
TS怎么实现类型安全?3个日常场景就能看明白
TS的类型安全不是空喊口号,而是通过具体的规则实现的,咱们看3个最常用的场景:
变量得先“定类型”,不能随便变
JS里你可以写let x = 1;,然后再写x = "苹果";,这在TS里会直接报错——因为你一开始说x是数字,后来改成字符串,违反了类型约定。就像你买青菜,不能先定好买1斤,又临时改成买1个,这会被帮你拎菜的人提醒“类型不对”。
当然,TS也不会完全死板,要是你真的想让x既能是数字又能是字符串,就得提前说清楚let x: number | string = 1;,明确告诉它“这个变量两种类型都可以”,这样就不会报错了。
函数得“检查参数和返回值”,不能瞎传
咱们写个计算总价的函数,JS里可能写function calcTotal(price, count) { return price * count; },要是你传了calcTotal("10", "5"),虽然JS会把字符串转成数字算出50,但要是传了calcTotal("10元", "5个"),就会得到NaN(不是数字),查半天找不到原因。
但在TS里,你得先给参数定类型:function calcTotal(price: number, count: number): number { return price * count; },这时候你传字符串或者“10元”,TS直接在写代码的地方就标红报错,告诉你“参数类型不对”,从源头避免了无效计算。而且它还会检查返回值,要是你函数里不小心没写return,或者return了字符串,也会报错。
对象和数组得“对应上结构”,不能乱拿属性
假设你有个用户对象,JS里写const user = { name: "小明", age: 18 };,要是你想拿user.address,JS会返回undefined,你只能 runtime 才发现问题。
TS里可以定义一个“用户模板”(叫接口):interface User { name: string; age: number; },然后把user声明成这个类型const user: User = { name: "小明", age: 18 };,这时候你写user.address,TS会立刻报错,告诉你“这个对象没有address属性”,就像你拿了青菜的袋子,不能随便找猪肉的标签贴上去。
数组也是一样,要是你声明const numbers: number[] = [1,2,3];,往里面加字符串的话,TS会直接报错。
不是“限制”,是“省时间的工具”
很多人觉得TS的类型安全是在“给自己加约束”,但其实它是帮你省了debug的时间。有了类型检查,你写代码时就能提前发现90%的类型错误,不用等到上线后再查。就像买菜时有人帮你盯着类型,不用等到回家才发现买错了,浪费时间。
当然,TS的类型安全也不是万能的,要是你故意写any(跳过类型检查),那它也帮不了你,但只要你合理用类型,它就能帮你把代码里的“隐形坑”一个个填上,让写代码更省心。