学径XUEJING · 个人学习平台通知设置

课程库 TypeScript TypeScript 起步 › 第 1

为什么需要类型 —— 从一个 JS 运行时惨案讲起

普通课45 分钟

本课导读

欢迎来到 TypeScript。本单元假设你已经会任何一门语言的变量、函数和循环(JS 经验加分但不必须)——我们直接从"为什么"讲起:先亲眼目睹一场 JavaScript 的运行时惨案(代码没报错、结果悄悄错了),再看 TypeScript 如何把同一个事故拦在运行之前。看懂这场对比,你就理解了 TS 存在的全部理由。预计 45 分钟。

说明

本课程代码块的运行方式:点「▶ 运行」会先做完整的类型检查,检查通过才执行。有些示例的教学目标就是"让你看到报错"——这类代码块会用注释标注 // 预期报错:TSxxxx,红字出现即为"运行成功"。首次运行需加载 TS 编译器(几秒),之后流畅。

惨案现场:一个没有报错的 bug

电商结算页:单价 299,用户买 2 件,外加 15 元运费。数量从表单输入框读进来——而输入框给你的永远是字符串 "2"。下面用 any 类型模拟"JS 不设防"的世界(any 的含义课末揭晓):

TypeScript

运行看输出:应付金额 "299215"——没有报错、没有警告,程序"正常"跑完了。发生了什么:

  • JS 是动态类型语言:变量装什么类型的值全看运行时,代码写错了它也照单全收
  • + 遇到字符串就变"拼接":299 + "2""2992",再 + 15"299215"
  • 最可怕的不是出错,是错得无声无息——这个数字会一路流到支付接口、订单记录、财务报表。等有人发现,可能已经是月底对账的时候

提示

类比记忆:动态类型像不核对币种的收银台——你递 200 日元,它当 200 美元收了,账面"完全正常"。事故不发生在收钱那一刻,而发生在月底盘点时——离案发现场越远,排查越贵。

同一个事故,TypeScript 的处理方式

TS 的解法:给函数的参数贴上类型标签,字符串根本进不了结算逻辑:

TypeScript

点运行——红字,代码根本没有执行TS2345: Argument of type 'string' is not assignable to parameter of type 'number'(类型为 string 的实参不能赋给类型为 number 的形参)。读懂这次拦截:

  • price: number 这种冒号语法是类型标注:给参数立门禁规矩——"只收数字"
  • 字符串 "2" 想混进去,编译阶段(代码运行之前)当场按住——事故从"月底对账才发现"提前到"写代码的这一秒"
  • 修法也简单:把字符串转成数字再传,checkout(299, Number(qtyFromForm))——练习 1 就是它

再看一个 JS 里更高频的惨案——拼写错误

TypeScript

在 JS 里,order.pirce 静默返回 undefined,乘出个 NaN 一路传下去。TS 不但当场报错,还猜出了你的心思Did you mean 'price'?(你是不是想写 price?)——类型系统认识你对象上的每一个属性。

类型到底是什么

用两句话把概念立正:

  1. 类型 = 值的"种类"标签299 是 number、"2" 是 string、true 是 boolean。所有语言的值都有类型,区别只在谁来查、什么时候查
  2. TS 的核心动作 = 静态检查:代码还没运行,先把整个程序的类型账算一遍——"这里该是数字,你给了字符串"。像出发前的行前体检,而 JS 是"上了高速才发现刹车有问题"

TS 和 JS 的关系一句话说清:TypeScript = JavaScript + 类型说明书。TS 代码经过"编译"脱掉类型外衣变成纯 JS,浏览器最终跑的还是 JS——所以 TS 没有另起炉灶,你写的每一行 JS 知识都不作废,类型是上去的安全层。

为什么此刻的你更需要它

类型系统最值钱的三个场景,恰好都在你的未来路线上:

  • 项目变大:三百行以内 JS 随便写;三千行起,"这个函数到底接受什么参数"全靠记忆和祈祷——类型让代码自带答案
  • 接手别人的代码:函数签名 checkout(price: number, qty: number): number 本身就是最准的文档——不会过期、不会撒谎
  • AI 时代(最重要):让 AI 写代码已是日常,但 AI 会一本正经地编造不存在的属性、传错类型的参数。类型检查是 AI 产出的自动验收员——幻觉代码在编译那一刻当场现形,而不是溜进生产环境。学 TS 不只是学一门语言,是给你的 AI 协作流程装质检closed环
  • 最后揭晓 any:它是 TS 里"关掉类型检查"的后门——本课开头用它模拟 JS 世界。规矩从第一课立下:教学演示之外,不用 any(用了它,TS 的保护就对这段代码失效了)

✍️ 练习

练习 1:修复结算函数

把惨案现场修好:表单来的 qtyFromForm 转成数字再传给 checkout(提示:Number(字符串) 完成转换)。修好后应付金额应该是 613。

TypeScript
✅ 参考答案
function checkout(price: number, qty: number): number {
    return price * qty + 15;
}

const qtyFromForm = "2";

const total = checkout(299, Number(qtyFromForm));

console.log("应付金额:" + total);

注意修法的含义:不是把类型标注删掉息事宁人,而是在边界处把数据洗成正确类型——"表单进来的都是字符串,入口处转换"从此是你的肌肉记忆。

练习 2:抓拼写小偷

下面代码有两处属性拼写错误(JS 里它们会静默产出 NaN 和 undefined)。先别运行,肉眼找;然后运行,看 TS 的报错是否和你找的一致,修复它们。

TypeScript
✅ 参考答案
const product = { name: "机械键盘", price: 599, stock: 12 };

console.log(product.name + " 库存 " + product.stock + " 件");
console.log("含税价 " + product.price * 1.06);

stcokprise——TS 的报错里都带着 Did you mean 提示,等于抓贼还附赠画像。这类错误在纯 JS 项目里是排查耗时冠军。

练习 3:预言家挑战

三段代码,先预测各自的命运(通过运行 / 编译报错),再逐段取消注释验证。想想各自的理由。

TypeScript
✅ 参考答案

段一:报错(TS2363,算术运算的右侧必须是数字)。段二:通过!输出 "2992" string——TS 沿袭了 JS 的 + 拼接语义,这是它少数"放行危险动作"的地方(毕竟字符串拼接太常用),所以+ 保持警惕这条 JS 时代的戒律在 TS 里依然有效。段三:报错(TS2345,两个参数类型都对不上位)。

三段的启示:TS 拦得住绝大多数类型事故,但不是全部——它是安全带,不是免死金牌。

📝 随堂测验

随堂测验0 / 5 题正确

1. JS 里 299 + "2" + 15 得到 "299215" 且不报任何错,这类问题最大的危害是?

2. TypeScript 的“静态检查”指的是?

3. TypeScript 和 JavaScript 的关系是?

4. order.pirce(拼写错误)在 JS 和 TS 里的遭遇分别是?

5. 为什么说 AI 时代类型检查更重要了?

本课小结

  • JS 动态类型的代价:错得无声无息("299215" 惨案、拼写返回 undefined)——事故离现场越远越贵
  • TS 的答案:类型标注(price: number)+ 静态检查——事故提前到编译时,还附赠 Did you mean
  • TS = JS + 类型说明书,编译后仍是 JS;+ 拼接等少数语义仍需警惕——安全带不是免死金牌
  • AI 时代的新理由:类型是 AI 生成代码的自动验收员
  • 立规矩:教学演示之外不用 any(它是关掉保护的后门)

下一课正式盘点基础类型(string/number/boolean/数组),以及 TS 最贴心的设计——类型推断:能不写类型的地方就不写,让编译器替你干活。

划选正文任意文字可高亮、批注或加入复习卡

讨论

载入中…