LESSON 4.3 / MODERN FRONTEND

TypeScript:先把数据形状说清楚

TypeScript 让数据形状在运行前接受检查。它能尽早发现字段和参数对不上,但接口返回的真实数据仍要在运行时验证。

预计阅读约 25 到 40 分钟
完成结果为任务、筛选条件和新增函数补上类型,并能解释一次故意制造的类型错误。
本课目标
  • 为任务、筛选条件和新增函数补上类型,并能解释一次故意制造的类型错误。
  • 类型标注、类型推断与编译检查
  • 复现TypeScript:先把数据形状说清楚后,应当为任务、筛选条件和新增函数补上类型,并能解释一次故意制造的类型错误,并保留类型检查、生产构建、浏览器行为和请求结果作为可重复检查的依据。
开始之前
  • 完成 4.2「Node.js、npm 与构建工具」
01

FOUNDATION

必须理解

JavaScript 只有运行到某一行时,才会暴露一部分数据形状错误。TypeScript 在开发和构建阶段检查类型,让许多拼写、字段和参数问题提前出现。

本课依次讲清类型标注、类型推断与编译检查、对象类型、联合类型和可选字段和类型只在开发阶段检查,不代替运行时校验,最后通过“恢复正确代码并运行生产构建,记录类型检查结果”检查学习结果。

先建立整体直觉

类型像接口旁边的交接单。它写明下一步会收到哪些字段、哪些可以缺省、函数会交回什么。交接单能发现双方写法不一致,却不能保证箱子里的实物一定正确。

贯穿本课的实际场景

任务应用用 Task 类型约定 id、title 和 done。筛选条件只能取 all、open 或 completed,组件与函数都沿用同一份数据形状。

概念 1

类型标注、类型推断与编译检查

先用白话理解

有些类型可以由代码推断出来,不必每个变量都手写。函数参数和公开数据边界更值得明确标注,因为错误常从这些地方传到别处。

基础概念

TypeScript 在 JavaScript 语法上增加类型检查。编辑器和构建工具可以在运行前比较变量、参数和返回值是否符合约定。

进一步理解

类型推断会根据初始值判断一部分类型,所以局部变量通常不必重复标注。函数参数和模块输出是数据交接位置,更适合明确写出类型。

类型错误不是程序运行后的异常,它是在告诉你两处代码对同一份数据有不同理解。修复前先读清期望类型与实际类型。

放进实际场景

addTask 要求 title 是字符串。调用者传入数字时,编辑器会在运行前指出参数不符合函数约定。

容易混淆的地方

类型检查不能证明业务结果正确。两个字符串相加通过检查,也可能不符合产品需要的标题规则。

这一小节记住:把类型放在数据边界上,用报错发现代码理解不一致。

概念 2

对象类型、联合类型和可选字段

先用白话理解

对象类型描述字段,联合类型把可选值限制在几个明确结果中,问号表示字段可以缺少。它们能让编辑器在你输入时就指出不一致。

基础概念

对象类型描述一组字段及各自类型。联合类型把一个值限制在几个明确选项内,可选字段则表示这个字段允许暂时不存在。

进一步理解

Task 类型统一 id、title 和 done 后,列表、表单和接口都可以复用同一份定义。字段变化只需要从这个来源开始检查影响。

`all | open | completed` 这样的联合类型比普通 string 更窄。拼错筛选值时,代码不必等到页面出现空结果才发现。

放进实际场景

任务可以有可选 dueDate,但 title 与 done 必须存在。筛选组件只接收 TaskFilter 允许的三种值。

容易混淆的地方

可选字段表示字段可能缺少,不表示任何类型都能放进去。存在 dueDate 时,它仍然要符合声明的类型。

这一小节记住:类型名称应表达产品中的真实数据,不围着某个页面临时命名。

概念 3

类型只在开发阶段检查,不代替运行时校验

先用白话理解

TypeScript 的类型在编译后不会替你检查网络响应。接口返回的内容仍然来自运行时,程序必须另外校验,不能因为写了类型就直接信任。

基础概念

TypeScript 类型在编译后不会继续检查运行中的值。网络响应、用户输入和本地存储都来自运行时,进入系统时仍需校验。

进一步理解

直接把未知数据断言成 Task 只是在告诉检查器相信开发者,并没有查看真实字段。外部数据应先作为 unknown,再逐项判断。

运行时校验通过以后,代码才能安全地把结果交给需要 Task 的函数。失败时要返回可处理的错误,不能让缺字段数据继续传播。

放进实际场景

接口返回一条记录时,程序检查它是不是对象,是否有字符串 title 和布尔值 done。通过后再显示为任务。

容易混淆的地方

类型标注描述开发者的预期,运行时校验检查收到的真实内容。两者互相配合,不能互相替代。

这一小节记住:项目外部的数据先校验,内部代码再享受类型带来的提示。

任务数据的明确边界
运行前先确认
  • 项目已经启用 TypeScript,并能运行类型检查或生产构建。
  • 代码示例只定义数据形状,不会在运行时创建任务。
type Task = {
  id: string;
  title: string;
  done: boolean;
};

type TaskFilter = "all" | "open" | "completed";
这段代码在做什么

阅读TypeScript:先把数据形状说清楚示例时,Task 统一任务字段,TaskFilter 把筛选值限制在界面确实支持的三种状态。

  1. Task 统一任务对象必须拥有的三个字段。
  2. 每个字段右侧写出允许的值类型,缺少或写错都会触发检查。
  3. TaskFilter 使用联合类型,调用者不能传入列表之外的筛选字符串。
你应该观察到

编辑器可以提示缺少 title 或 done 的任务对象,也会拒绝拼错的筛选值;代码运行时不会额外生成类型检查逻辑。

02

AI COLLABORATION

AI 如何参与

在TypeScript:先把数据形状说清楚这一课,AI 负责根据真实材料解释类型标注、类型推断与编译检查并指出遗漏,学习者负责控制范围、执行修改和核对类型检查、生产构建、浏览器行为和请求结果。

推荐协作顺序

  1. 1

    先挑一条真实任务数据,让 AI 解释各字段当前是什么类型。

  2. 2

    从函数参数和返回值开始加类型,不一次改完整项目。

  3. 3

    逐条处理类型错误,确认代码意图后再修改,不用 any 压住提示。

可直接使用的 Prompt
这是任务数据和 TypeScript 报错。请先用白话解释期望类型与实际类型,再指出最小修改位置。不要使用 any、双重断言或关闭检查。最后说明哪些外部数据仍需要运行时校验。
应该得到什么

类型名称与任务领域一致,函数边界清楚。回答会明确区分编辑器检查和真实接口数据校验;TypeScript:先把数据形状说清楚的人工验收必须回到真实页面、请求、终端、测试或数据结果,不能用 AI 的文字说明代替。

人工检查清单

  • 故意删掉必填字段、写错筛选值并传入未知接口数据,观察哪些问题由构建发现,哪些仍需自己处理。
  • 禁止 AI 用 any 或无依据的类型断言消除错误,要求它解释期望类型和实际类型。
  • 分别制造一个编译期字段错误和一个运行时接口错误,确认两类检查发生在不同位置。
03

COMMON TRAPS

常见误区

下面三类问题会让任务看似完成,却经不起刷新、错误输入或真实环境检查。先看现象,再找原因和修正方法。

误区 1

用 any 消掉错误

你会看到
红线消失,错误数据仍会进入程序
为什么发生
any 会关闭后续类型检查,数据结构不符的问题只是被推迟到运行时。
怎样纠正
修正数据边界或收窄未知值
误区 2

用断言代替证据

你会看到
告诉编译器相信自己,却没有验证数据
为什么发生
类型断言不会检查真实数据,它只要求编译器停止质疑当前写法。
怎样纠正
在外部输入处做运行时检查
误区 3

把所有字段设为可选

你会看到
代码处处处理缺失,模型失去约束
为什么发生
模型不再表达哪些信息必须存在,缺失值处理会扩散到每个使用位置。
怎样纠正
只为业务上确实可缺省的字段加问号
04

HANDS-ON

动手任务

为任务、筛选条件和新增函数补上类型,并能解释一次故意制造的类型错误。

准备条件
  • 完成 4.2「Node.js、npm 与构建工具」

跟着做

  1. 01

    把任务项目切换到 TypeScript 并确认原功能仍可运行。

  2. 02

    定义 Task 与 TaskFilter,替换散落的数据形状。

  3. 03

    为新增、切换和筛选函数标注参数与返回值。

  4. 04

    故意制造缺字段和错误筛选值,读取完整报错。

  5. 05

    恢复正确代码并运行生产构建,记录类型检查结果。

完成标志

为任务、筛选条件和新增函数补上类型,并能解释一次故意制造的类型错误。

加餐挑战

把一段未知 JSON 转成 Task。先检查字段,再返回可用数据或清楚的失败结果。

离开本课前,自问四件事

  • 类型推断与显式标注分别适合什么位置?
  • 对象类型、联合类型和可选字段各解决什么问题?
  • 为什么 any 会让后续类型提示失去价值?
  • 哪类数据即使写了 TypeScript 仍必须运行时校验?
完成本课了吗?

确认完成后,会同步更新学习中心的课程学习进度。