面向初学者的 TypeScript

恭喜你选择 TypeScript 作为你的首选语言之一——你已经做出了明智的选择!

你可能已经听说过 TypeScript 是 JavaScript 的一种“口味”或“变体”。在现代编程语言中,TypeScript (TS) 与 JavaScript (JS) 之间的关系相当独特,因此深入了解这种关系将有助于你理解 TypeScript 是如何增强 JavaScript 的。

什么是 JavaScript?简要历史

JavaScript(也称为 ECMAScript)最初是作为浏览器的一种简单脚本语言而诞生的。在它发明之初,人们预期它仅用于网页中嵌入的简短代码片段——编写几十行以上的代码在当时是相当少见的。因此,早期的 Web 浏览器执行此类代码的速度非常慢。然而,随着时间的推移,JS 变得越来越流行,Web 开发人员开始使用它来创建交互式体验。

Web 浏览器开发者通过优化其执行引擎(动态编译)和扩展其功能(添加 API)来响应 JS 使用量的增加,这反过来又促使 Web 开发者更多地使用它。在现代网站上,你的浏览器经常运行着跨越数十万行代码的应用程序。这是“网络”漫长而渐进的发展历程,它从一个简单的静态页面网络演变成了一个承载各种丰富应用程序的平台。

不仅如此,JS 已经变得足够流行,可以在浏览器环境之外使用,例如使用 node.js 实现 JS 服务器。“随处运行”的 JS 特性使其成为跨平台开发的理想选择。如今,许多开发人员使用 JavaScript 来编写他们的整个技术栈!

总结一下,这门语言最初是为快速使用而设计的,后来成长为编写数百万行代码应用程序的完整工具。每种语言都有自己的怪癖——即奇特之处和意外,JavaScript 卑微的开端导致它拥有许多这样的怪癖。以下是一些例子:

  • JavaScript 的相等运算符 (==) 会对其操作数进行强制类型转换,从而导致意外行为

    js
    if ("" == 0) {
    // It is! But why??
    }
    if (1 < x < 3) {
    // True for *any* value of x!
    }
  • JavaScript 还允许访问不存在的属性

    js
    const obj = { width: 10, height: 15 };
    // Why is this NaN? Spelling is hard!
    const area = obj.width * obj.heigth;

大多数编程语言在出现此类错误时会抛出错误,有些甚至会在编译阶段(代码运行之前)就进行报错。在编写小程序时,这些怪癖虽然令人讨厌但尚可应付;而在编写成百上千行代码的应用程序时,这些不断出现的意外就会成为严重的问题。

TypeScript:静态类型检查器

我们之前说过,有些语言根本不允许这些有错误的代码运行。在不运行代码的情况下检测错误被称为静态检查。根据操作值的类型来确定是否为错误,这被称为静态类型检查。

TypeScript 在程序执行前对其进行检查,并根据值的类型进行检查,因此它是一个静态类型检查器。例如,上面最后一个示例中存在错误,原因在于 obj类型。这是 TypeScript 发现的错误:

ts
const obj = { width: 10, height: 15 };
const area = obj.width * obj.heigth;
Property 'heigth' does not exist on type '{ width: number; height: number; }'. Did you mean 'height'?2551Property 'heigth' does not exist on type '{ width: number; height: number; }'. Did you mean 'height'?
Try

JavaScript 的类型化超集

那么,TypeScript 与 JavaScript 是什么关系呢?

语法

TypeScript 是一门 JavaScript 的超集:因此,JS 语法即是合法的 TS 语法。语法指的是我们编写文本以构成程序的方式。例如,这段代码因为缺少一个 ) 而存在语法错误

ts
let a = (4
')' expected.1005')' expected.
Try

TypeScript 不会将任何 JavaScript 代码视为语法错误。这意味着你可以将任何有效的 JavaScript 代码放入 TypeScript 文件中,而不必担心它的编写方式。

类型

然而,TypeScript 是一个类型化的超集,这意味着它增加了关于如何使用不同类型值的规则。之前关于 obj.heigth 的错误不是语法错误:它是以错误的方式使用某种值(类型)的错误。

再举一个例子,这是你可以在浏览器中运行的 JavaScript 代码,它记录一个值

js
console.log(4 / []);

这个语法合法的程序会记录 Infinity。然而,TypeScript 认为用数组除以数字是一种毫无意义的操作,因此会发出错误。

ts
console.log(4 / []);
The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.2363The right-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
Try

有可能你确实打算用数字除以数组,也许只是为了看看会发生什么,但大多数情况下,这都是一个编程错误。TypeScript 的类型检查器旨在允许正确的程序通过,同时尽可能多地捕获常见错误。(稍后,我们将学习如何配置 TypeScript 对代码的检查严格程度。)

如果你将某些代码从 JavaScript 文件移动到 TypeScript 文件中,你可能会看到类型错误,具体取决于代码的编写方式。这些可能是代码中的合法问题,或者是 TypeScript 过于保守。在本指南中,我们将演示如何添加各种 TypeScript 语法来消除此类错误。

运行时行为

TypeScript 也是一种保留 JavaScript 运行时行为的编程语言。例如,在 JavaScript 中,除以零会产生 Infinity,而不是抛出运行时异常。作为原则,TypeScript 永远不会改变 JavaScript 代码的运行时行为。

这意味着如果你将代码从 JavaScript 移动到 TypeScript,即使 TypeScript 认为代码有类型错误,它也保证能以相同的方式运行。

保持与 JavaScript 相同的运行时行为是 TypeScript 的一项基本承诺,这意味着你可以轻松地在两种语言之间转换,而不必担心会导致程序无法运行的细微差异。

类型擦除

粗略地说,一旦 TypeScript 编译器完成对代码的检查,它就会擦除类型以生成最终的“编译后”代码。这意味着一旦代码编译完成,生成的普通 JS 代码中就不包含任何类型信息。

这也意味着 TypeScript 永远不会根据它推断出的类型来改变你程序的行为。归根结底,虽然你在编译时可能会看到类型错误,但类型系统本身对程序运行时的运作方式没有任何影响。

最后,TypeScript 不提供任何额外的运行时库。你的程序将使用与 JavaScript 程序相同的标准库(或外部库),因此不需要学习任何特定于 TypeScript 的框架。

学习 JavaScript 和 TypeScript

我们经常看到这样的问题:“我应该学习 JavaScript 还是 TypeScript?”。

答案是:不学习 JavaScript 就无法学习 TypeScript!TypeScript 与 JavaScript 共享语法和运行时行为,因此你学习 JavaScript 的任何知识都在同时帮助你学习 TypeScript。

程序员可以学习 JavaScript 的资源非常多;如果你在编写 TypeScript,不应忽略这些资源。例如,StackOverflow 上标记为 javascript 的问题大约是 typescript 的 20 倍,但所有 javascript 问题也适用于 TypeScript。

如果你发现自己在搜索类似“如何在 TypeScript 中对列表进行排序”之类的内容,请记住:TypeScript 就是带有编译时类型检查器的 JavaScript 运行时。你在 TypeScript 中对列表排序的方式与在 JavaScript 中相同。如果你找到的资源直接使用了 TypeScript,那当然也很好,但不要局限于认为在处理日常运行时任务时,必须寻找特定于 TypeScript 的答案。

后续步骤

这是对日常 TypeScript 中使用的语法和工具的简要概述。从这里开始,您可以

TypeScript 文档是一个开源项目。通过发送 Pull Request 来帮助我们改进这些页面 ❤

此页面的贡献者
OTOrta Therox (19)
EBEli Barzilay (2)
XLXavi Lee (1)
NSNick Schonning (1)
AOAlex Ownejazayeri (1)
8+

最后更新:2026 年 3 月 27 日