L.Leverage Learn从第一行代码,到读懂真实后端查看项目源码

TypeScript 基础 / 第 7 课

类型检查到哪里为止

了解 TypeScript 编译如何检查代码、类型擦除意味着什么,以及运行时验证为何仍有必要。

◷ 预计 9 分钟 · 面向初学者

浏览器执行的是 JavaScript。写 TypeScript 时,需要先经过编译:工具读取代码和类型,检查许多可静态判断的问题,再生成 JavaScript。生成结果保留可执行的语句,不保留大多数类型标注。这个过程常称为类型擦除。

例如:

function greet(name: string): string {
  return `你好,${name}`;
}

const message: string = greet('小林');

编译后的 JavaScript 中,: string 不再出现,函数仍会把传入的值放进文字里。类型让编写和维护代码时更容易发现错误,但它不是 JavaScript 的运行时规则。编译器不会因为类型标注而替程序把输入转成字符串,也不会在每次函数调用时额外检查它。

异步函数也可以说明结果类型:

async function readGreeting(): Promise<string> {
  return '早上好';
}

readGreeting().then((text) => console.log(text));

Promise<string> 表示这个 Promise 成功完成时会得到字符串。async 函数会返回 Promise;调用方可以用 await 或 .then() 读取完成值。这个类型帮助编译器检查函数实现和调用方式,运行时真正工作的仍是 JavaScript 的 Promise 对象。若要处理可能失败的情况,还需要单独理解拒绝状态;Promise<string> 并不会保证操作一定成功。

静态检查也不是万能证明。比如数据来自用户输入或文件,TypeScript 通常无法仅靠类型声明确认实际内容。可以把一段文字直接断言成某个对象类型,但断言只是在告诉编译器“按这个类型看待”,不会验证里面的字段。若运行时数据不符合预期,读取属性或调用方法仍可能出错。需要时应在运行时检查值,再决定如何使用它。

可以把类型理解成开发阶段的约定,而不是附着在每个 JavaScript 值上的标签。编译成功说明检查器没有发现它能识别的类型问题,不等于程序绝无错误,也不等于外部数据已验证。

小练习:const age: number = 18 编译后,变量上还带着 number 标签吗?把任意文字断言为 { name: string } 会检查文字内容吗?

答案:不会,: number 会在生成 JavaScript 时擦除。断言不会检查文字内容;要确认运行时数据有效,必须实际读取并检查它的结构和值。

互动练习:理解编译边界

TypeScript 编译成 JavaScript 后,哪项通常会被移除?

选择一个答案

✓
这一课,你已经能……

编译阶段能发现静态类型不匹配,但类型会从生成的 JavaScript 中擦除,不能代替运行时检查。